2

我正在研究一个 coursera 示例,Signal但无法理解这种语法,

class Signal[T](expr: => T) {
 import Signal._
 private var myExpr: () => T = _
 private var myValue: T = _
 private var observers: Set[Signal[_]] = Set()
 private var observed: List[Signal[_]] = Nil
 update(expr)

更新方法写为

    protected def update(expr: => T): Unit = {
    myExpr = () => expr
    computeValue()
  }

我可以理解这expr是按名称传递的,因此仅在调用时才进行评估。但是我无法理解的是为什么myExpr表示为() => T?还有为什么作业写成myExpr = () => expr. 据我了解() => expr,表示返回的 Function0 expr。我认为我的理解byname是错误的。有人可以详细说明一下吗?

或者我们可以重写上面的语法如下,

  class Signal[T](expr: () => T) {
  import Signal._
  private var myExpr: () => T = _
  private var myValue: T = _
  private var observers: Set[Signal[_]] = Set()
  private var observed: List[Signal[_]] = Nil
  update(expr)

更新方法为

 protected def update(expr: () => T): Unit = {
    myExpr = expr
    computeValue()
  }
4

1 回答 1

2
expr: => T

as 函数参数代表按名称调用,它不仅是延迟评估(也称为惰性),而且每次访问时都会对其进行评估。

private var myExpr: () => T = _

表示它是一个类型的变量,() => T这意味着它不接受任何参数并返回T。如果你把expr: () => T它作为函数参数,它会产生一个类型的参数,() => T这再次意味着它不接受任何参数并返回T,这不是按名称调用。由于语法相似,这两件事有点令人困惑,但又完全不同。

你可以像这样使用它:

myExpr = () => 4
myExpr() //evaluates as 4

myExpr()而没有分配给它的调用() => 4会抛出java.lang.NullPointerException.

在 coursera 课程中,Odersky 用他的例子很好地解释了什么是点名评估。def loop: Unit = loop

于 2016-07-14T07:59:38.097 回答