2016-03-20 31 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