8

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

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 
}
4

2 回答 2

12

为方便起见,Scala 允许您在调用方法时省略空括号,但它足够聪明地看到第一种情况下的预期类型是()=>Unit,因此它不会为您删除所有括号;相反,它会将方法转换为您的函数。

然而,在这种val check情况下,它看起来就像一个函数调用结果被分配给一个变量。事实上,所有这三个都做完全相同的事情:

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

如果要将方法转换为函数,请放置_在方法之后以代替参数列表。因此,

val check = dream() _

会做你想做的。

于 2010-05-20T04:49:41.723 回答
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部分应用的方法转换为函数。这不是一个简单的任务。Scala 进行转换是因为类型推断器可以猜出正确的类型。

val check = dream()         // unexpected invocation

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

于 2010-05-20T15:39:19.877 回答