0

在“Scala in Depth”中有一个例子,作者解释了 scala 如何对传递给方法的参数进行某种程度的推断。例如,如下所示:

def myMethod(functionLiteral: A => B):Unit
myMethod({ arg:A => new B})
myMethod({ arg => new B})

为了弄清楚作者在说什么,我在 REPL 中做了以下操作:

def myMethod(functionLiteral: Boolean => Boolean):Unit = {}
myMethod({a:Boolean => true})
myMethod({a => true})

这里发生的唯一具有启发性的事情是编译器不会抛出错误。

作者是否想说编译器将函数参数 a 推断为布尔值?

4

2 回答 2

2

作者是否想说编译器将函数参数 a 推断为布尔值?

绝对地。给定以下方法:

def myMethod(functionLiteral: Boolean => Boolean):Unit = {}

编译器知道参数 tomyMethod是一个接受布尔参数的函数,因此不需要您指定它。换句话说,以下a是明确的布尔参数:

myMethod{a => true}

现在,值得注意的是,这在与重载混合时不再起作用:

def myMethod(functionLiteral: Boolean => Boolean):Unit = {}
def myMethod(functionLiteral: Int => Boolean):Unit = {}
myMethod{a => true} // error: missing parameter type

原因是它无法明确判断a是类型Boolean还是Int

于 2012-11-16T10:24:19.317 回答
2

是的,作者说不需要指定它aBooleaninmyMethod({a => true})因为类型是Boolean => Boolean

==原始答案使第一位编译但有点错过了==

它需要用 键入[A,B]

def myMethod[A,B](functionLiteral: A => B): Unit = {}
myMethod((arg:String) => arg.length)
myMethod((arg:Int) => (1 to arg).map(_ *2))

我修改它以返回函数,以便您可以看到 repl 中的类型。

scala> def myMethod[A,B](functionLiteral: A => B): A => B = functionLiteral
myMethod: [A, B](functionLiteral: (A) => B)(A) => B

scala> myMethod((arg:String) => arg.length)
res11: (String) => Int = <function1>

scala> res11("hello world!")
res12: Int = 12

scala> myMethod((arg:Int) => (1 to arg).map(_ *2))
res13: (Int) => scala.collection.immutable.IndexedSeq[Int] = <function1>

scala> res13(4)
res14: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8)
于 2012-11-16T04:32:33.943 回答