在为部分函数创建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
}
答案 0 :(得分:12)
为方便起见,Scala允许您在调用方法时省略空的parens,但它足够聪明,可以看到第一种情况中的预期类型是()=>Unit
,因此它不会为您删除所有的parens;相反,它会将方法转换为适合您的函数。
然而,在val check
的情况下,它看起来就像函数调用结果被分配给变量一样。事实上,所有这三个都完全相同:
val check = dream
val check = dream()
val check = dream()()
如果要将方法转换为函数,可以在方法之后放置_
代替参数列表。因此,
val check = dream() _
会做你想做的事。
答案 1 :(得分: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
这里没有预期类型来帮助类型推理器。但是,可以省略空参数列表,因此这只是一个方法调用。