假设我编写了一个接受函数的方法,并且有另一个函数返回一个函数。我可以这样写我的方法:
def logParens(f: () => String) = println(f())
或者像这样:
def logNoParens(f: => String) = println(f)
让我们说我有一个返回字符串的方法
def foo = "foo"
为什么我可以将foo直接传递到logNoParens
,而不是logParens
?似乎Scala会将foo
强制转换为=> foo
,然后再将其传递到logNoParens
。
logParens(foo) // this gives me a type error
logParens(() => foo) // this compiles
logNoParens(foo) // this compiles just fine
=>
和() =>
之间有什么区别?
答案 0 :(得分:0)
简而言之:() ⇒ String
创建类型为Unit ⇒ String
的函数,而⇒ String
表示类型为String
的 lazy 值作为参数传递,因此,如果引用,将在函数体中稍后不再重新评估。
当执行在代码中达到引用时,评估 仅 。
这种形式非常适用于创建接受某人的高阶函数,例如:
def func(f: ⇒ String) : Either[Exception, String]{
if (someCondition) {
Right(f)
} else {
Left(new IllegalArgumentException("F can't be evaluated")
}
}
可能的用法是:
def doF() {
func {
io.Stream.fromFile("path/to/file")
}
}
当然你可以改写如下:
def func(f: () ⇒ String) : Either[Exception, String]{
if (someCondition) {
Right(f())
} else {
Left(new IllegalArgumentException("F can't be evaluated")
}
}
可能的用法是:
def doF() {
func {
case _ ⇒ io.Stream.fromFile("path/to/file")
}
}
根据具体情况,您可以选择前者或后者,这些形式在上述情况下完全可以互换。唯一的区别是,如果你将 lazy 值传递给函数 - 它只会被评估一次,但是如果你将函数引用传递给函数 - 函数将会执行,评估结果传递到函数中的次数。