Scala 什么';“()=>;”之间的区别是什么还有“=>;”?
假设我写了一个接受函数的方法,还有另一个返回函数的函数。我可以这样写我的方法:Scala 什么';“()=>;”之间的区别是什么还有“=>;”?,scala,Scala,假设我写了一个接受函数的方法,还有另一个返回函数的函数。我可以这样写我的方法: def logParens(f:()=>String)=println(f()) 或者像这样: def logNoParens(f: => String) = println(f) 假设我有一个返回字符串的方法 def foo = "foo" 为什么我可以将foo直接传递到logNoParens,而不是logParens?似乎Scala将foo强制为=>foo,然后将其传递到logNoParens log
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
=>
和()=>
之间有什么区别?简而言之:()⇒ 字符串
创建类型为单元的函数⇒ 字符串
while⇒ 字符串
表示惰性类型字符串
的值作为参数传递,因此如果引用该值,以后不会在函数体中重新计算该值
因此,当执行到达代码中的引用时,它将被计算一次,而当作为参数传递时,不会被计算
这种形式在创建接受某人的高阶函数时非常常见,例如:
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 doF() {
func {
case _ ⇒ 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 {
io.Stream.fromFile("path/to/file")
}
}
def doF() {
func {
case _ ⇒ io.Stream.fromFile("path/to/file")
}
}
根据上下文,您可以选择前一种形式或后一种形式,这些形式在上述情况下完全可以互换。唯一的区别是,如果将惰性值传递给函数,它将只计算一次,但是,如果您将函数引用传递给函数-函数将执行,并且计算结果将传递给函数的次数与函数中使用的次数相同。正如雄心勃勃的用户所引用的那样,将参数添加到
def foo()
以获得eta扩展。谢谢,@som snytt。这类问题对谷歌来说很难回答。我还没有尝试过,但信息页面上说要搜索Stack Overflow中的Scala符号,如“=>”,可以使用symbolhound搜索。似乎每次在函数体中引用时都会对其进行计算<代码>定义日志(x:=>Int)=1到3 foreach{{u=>println(x)};var z=0;log{z=z+1;z}此示例记录1、2、3