2016-03-20 33 views
3

以下是兩個部分功能,預計執行sme任務,但以不同方式定義。直接應用提升功能不給予預期功能

val pf1 : PartialFunction[String, String] = { 
    case s : String if (s != null) => s.toUpperCase() 
} 
//> pf1 : PartialFunction[String,String] = <function1> 

val lift1 = pf1.lift 
//> lift1 : String => Option[String] = <function1> 

val d1 = lift1(null) 
//> d1 : Option[String] = None 

val d2 = lift1("hello world") 
//> d2 : Option[String] = Some(hello world) 

val pf2 = PartialFunction[String, String] { 
    case s : String if(s != null) => s.toUpperCase() 
} 
//> pf2 : PartialFunction[String,String] = <function1> 

val lift2 = pf2.lift 
//> lift2 : String => Option[String] = <function1> 

val d3 = lift2(null) 
//> scala.MatchError: null 

val d4 = lift2("hii") 
//> d4 : Option[String] = Some(hii) 

爲什麼傳遞null到lift2給MatchError,當兩個lift1和lift2的定義是一樣的嗎?

+0

Jeez,夥計,評論_的差異。我花了10分鐘盯着'if'和's'之間的空格(',試圖弄清楚爲什麼這很重要。)(對於其他人的線索,在類型聲明之後的'='是重要的。 – Malvolio

回答

1

如果你看一下PartialFunction.apply,你會看到它有點不同的東西,那麼你已經期待什麼:

/** Converts ordinary function to partial one 
    * @since 2.10 
    */ 
    def apply[A, B](f: A => B): PartialFunction[A, B] = { case x => f(x) } 

所以它封裝了正常功能成是在所有域定義的部分功能。這就是爲什麼當你舉起,您會收到例外 - 因爲裏面仍然是一個正常的未解除部分功能,這是沒有定義

0

爲什麼傳遞null到lift2給MatchError,當 都lift1和lift2定義是一樣的?

它們的定義不一樣。當你定義:

val pf1: PartialFunction[String, String] = { 
    case s : String if (s != null) => s.toUpperCase() 
} 

編譯器創建一個PartialFunction,像這樣:

this.pf1 = ({ 
    new <$anon: Function1>() 
    }: PartialFunction); 

但是,當你聲明pf2這樣的:

val pf2 = PartialFunction[String, String] { 
    case s : String if(s != null) => s.toUpperCase() 
} 

你實際上是在告訴編譯器「請拿這個Function1並把它傳遞給PartialFunction.apply。這就是編譯器這樣做的原因:

this.pf2 = scala.PartialFunction.apply({ 
    (new <$anon: Function1>(): Function1) 
}); 

其中實際包裝Function1在部分功能。因此,當您撥打pf2.lift(null)時,它會在內部呼叫Function1,導致您看到MatchError