传递参数()=>之间有什么区别? T和T

时间:2013-11-29 03:03:33

标签: scala

具体而言,遵循两个定义有何不同之处:

  def func(f: () => String) = f()
  def func1(s: String) = s

我写了一些代码来测试它们,似乎它们产生了相同的结果;在这种情况下,这两个定义是否相同;或者他们确实有一些区别?

  var x = 1

  def f() = {
    x = x + 1
    s"$x"
  }

  println(func1(f))
  println(func1(f))
  println(func1(f))

  println(func(f))
  println(func(f))
  println(func(f))

4 个答案:

答案 0 :(得分:2)

在这种情况下它们可能是相同的,但是当() => AA有很大不同时,还有很多其他情况。 () => A被称为thunk,用于将一段延迟计算传递给函数。在被调用的函数决定对其进行评估之前,“thunk”的主体不会被评估。 Otherwitse,传入的参数的值由调用者计算。

考虑这个例子,其中采用thunk的版本与仅采用值的版本之间存在差异:

    object Thunk {
  def withThunk(f: () ⇒ String): Unit = {
    println("withThunk before")
    println("the thunk's value is: " + f())
    println("now the thunk's value is: " + f())
  }

  def withoutThunk(f: String): Unit = {
    println("withoutThunk before")
    println("now the value's value is: " + f)
  }

  def main(argv: Array[String]): Unit = {
    withThunk { () ⇒ println("i'm inside a thunk"); "thunk value" }
    println("------------")
    withoutThunk { println("i'm not inside a thunk"); "just a value" }
  }
}

该计划将展示一些差异。在thunk版本中,你看到“withThunk before”在第一次“我在一个thunk里面”被打印之前被打印出来,打印两次,因为f()被评估两次。在非thunk版本中,“我不在thunk里面”在“之前的onThunk”之前被打印,因为这是在作为参数发送给函数之前被评估的。

答案 1 :(得分:1)

def func(f: () => String) = f()

这个接受一个返回字符串的函数作为参数。

def func1(s: String) = s

虽然这个简单需要String作为参数

除了上面的小技术差异之外,在这种情况下,它们似乎功能相同。但是,函数参数可能更强大,因为它是一个可以从其他几个操作派生返回值的函数。但是,我认为,函数参数允许您决定何时导出值的主要区别。

答案 2 :(得分:1)

我想添加一个使用() => String的示例。

def printFuncResult(f: () => String) = println(f() + " " + f())

def ran = () => Math.random.toString

printFuncResult(ran)
printFuncResult(Math.random.toString)

当您传递像ran这样的函数时,您很可能会打印两个不同的值(此处涉及随机性)。当您传递固定的随机数时,它将被打印两次。

正如您所看到的:当您将函数作为参数时,每次在printFuncResult中使用它时,它可能会产生不同的值。只需输入String参数即可实现此目的。

答案 3 :(得分:1)

def func(f: () => String) = f()
def func1(s: String) = s

println(func1(f)) // in this case f is evaluated first, its value is used in func1.

println(func(f)) // in this case f is NOT evaluated, but passed as it is to func.
                 // It is upto func to call f whenever needed, or even not call it.

这是f的“懒惰”评估,它使func更有用,例如f可以传递给其他一些更高阶的函数,或者它可以异步调用。