8

在创建String到部分函数的映射时,我遇到了意外的行为。当我创建一个局部函数作为地图元素时,它工作正常。当我分配给val时,它会调用。尝试调用该检查会生成一个错误。这是预期的吗?我在做些什么愚蠢的事情?注释掉check()以查看调用。我使用Scala的2.7.7什么时候是一个scala部分函数而不是部分函数?

def PartialFunctionProblem() = { 
    def dream()() = { 
     println("~Dream~"); 
     new Exception().printStackTrace() 
    } 
    val map = scala.collection.mutable.HashMap[String,()=>Unit]() 
    map("dream") = dream()  // partial function 
    map("dream")()    // invokes as expected 
    val check = dream()   // unexpected invocation 
    check()      // error: check of type Unit does not take parameters 
} 
+0

感谢您的帮助。当我用dream()_替换我的dream()调用时,它表现得如我所料。我会出去阅读关于PartialFunctions的更多内容,这样我就不会再误用这个术语。 – 2010-05-21 00:26:32

回答

12

为了方便,斯卡拉让你忽略调用方法时,空括号,但它聪明地看到,在第一种情况下预期的类型是()=>Unit,所以也没有为你删除所有的parens;相反,它将该方法转换为一个函数。

然而,在val check的情况下,它看起来就像一个函数调用结果被赋值给一个变量。事实上,所有这三个做同样的事情:

val check = dream 
val check = dream() 
val check = dream()() 

如果你想打开方法为功能,您将_到位参数列表(S)的方法后。因此,

val check = dream() _ 

会做你想做的。

5

嗯,问题是你弄错了。 :-)

下面是一些概念错误:

def dream()() = { 
    println("~Dream~"); 
    new Exception().printStackTrace() 
} 

这不是一个局部函数。这是一个带有两个空参数列表的curried方法,它返回Unit

val map = scala.collection.mutable.HashMap[String,()=>Unit]() 

该映射中值的类型不是局部函数,而是函数。具体来说,Function0[Unit]。部分函数的类型为PartialFunction[T, R]

map("dream") = dream()  // partial function 

这里会发生什么事是,斯卡拉部分采用的方法转换成一个功能。这不是一项简单的任务。 Scala会进行转换,因为类型推理器可以猜出正确的类型。

val check = dream()   // unexpected invocation 

这里没有预期的类型来帮助类型推理。但是,可以省略空的参数列表,所以这只是一个方法调用。

相关问题