Scala:为什么我应该将别名参数保存为 Function0
Scala : Why should i save a by-name parameter as a Function0
我正在学习 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
表示 returns expr
的 Function0。
我认为我对 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()
}
expr: => T
as function argument 代表 call-by-name 这不仅是延迟求值(又名惰性),而且每次访问时都会求值。
private var myExpr: () => T = _
表示它是一个() => T
类型的变量,这意味着它不带参数和returns T
。如果你把 expr: () => T
作为函数参数,它会生成一个类型为 () => T
的参数,这再次意味着它没有参数,并且 returns T
不是 [=32] =]按名称调用。
由于语法相似,这两件事有点令人困惑,但完全不同。
你可以这样使用它:
myExpr = () => 4
myExpr() //evaluates as 4
而调用 myExpr()
而未将 () => 4
分配给它会抛出 java.lang.NullPointerException
.
在 coursera 课程中,Odersky 用他的 def loop: Unit = loop
示例很好地解释了什么是 call-by-name 评估。
我正在学习 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
表示 returns expr
的 Function0。
我认为我对 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()
}
expr: => T
as function argument 代表 call-by-name 这不仅是延迟求值(又名惰性),而且每次访问时都会求值。
private var myExpr: () => T = _
表示它是一个() => T
类型的变量,这意味着它不带参数和returns T
。如果你把 expr: () => T
作为函数参数,它会生成一个类型为 () => T
的参数,这再次意味着它没有参数,并且 returns T
不是 [=32] =]按名称调用。
由于语法相似,这两件事有点令人困惑,但完全不同。
你可以这样使用它:
myExpr = () => 4
myExpr() //evaluates as 4
而调用 myExpr()
而未将 () => 4
分配给它会抛出 java.lang.NullPointerException
.
在 coursera 课程中,Odersky 用他的 def loop: Unit = loop
示例很好地解释了什么是 call-by-name 评估。