`()=>`和`=>`之间有什么区别?

时间:2015-12-08 02:11:04

标签: scala

假设我编写了一个接受函数的方法,并且有另一个函数返回一个函数。我可以这样写我的方法:

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

=>() =>之间有什么区别?

1 个答案:

答案 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 值传递给函数 - 它只会被评估一次,但是如果你将函数引用传递给函数 - 函数将会执行,评估结果传递到函数中的次数。