"fields and methods are equivalent" 是什么意思?
What does "fields and methods are equivalent" mean?
在 'Effective Scala' 的 Laziness 部分,它说:
Fields in scala are computed by need when val is prefixed with lazy. Because fields and methods are equivalent in Scala (lest the fields are private[this])
'fields'和'methods'等价是什么意思?是不是比较强硬的说法?
主要原因可能是,lazy val
和 def
在使用之前计算(而不是在首次定义时)。
不同之处在于 lazy val
试图避免重新评估不变的值,这增加了将计算值保存在内存中的成本。
嗯,这只是意味着您可以通过 def
定义抽象 val
,通过 val
定义抽象 def
。
例如
trait Server {
def port:Int
}
有一个抽象函数,即port
。您肯定可以使用 def
实现(或定义或覆盖)它,例如
object DefaultServer extends Server {
override def port: Int = 80
}
但在这种情况下,每次访问 port
都会导致根本不需要的函数应用程序(或方法调用)。出于这个简单的原因,Scala 为我们提供了使用值
实现抽象 def
的可能性
object DefaultServer extends Server {
override val port: Int = 80
}
这同样适用于抽象值。您可以使用相同的语法定义抽象值:
trait Server {
val port: Int
}
您可以使用 def
:
覆盖它们
object DefaultServer extends Server {
override def port: Int = 80
}
稳定性
您可能想知道如果您用每次调用时给您不同值的 def
覆盖抽象 val
会发生什么。您会因为该项目是 val
而获得第一个计算值,还是每次调用它都会获得不同的值,因为实际实现是 def
.
例如:
object DefaultServer extends Server {
override def port: Int = scala.util.Random.nextInt()
}
幸运的是 Scala 编译器检测到这一点并抛出以下错误:
error: overriding value a in trait Server of type Int;
method a needs to be a stable, immutable value
override def port:Int = scala.util.Random.nextInt()
懒惰
当谈到懒惰时,这种统一的行为(以相同的方式处理字段和方法)非常有用。
首先注意 lazy
抽象值不存在,即你不能将抽象 val
定义为 lazy
.
另一方面,通过 lazy val
实现抽象 def
是完全合法且有用的。 lazy
值将仅在第一次调用时计算并记忆(缓存并用于以后的调用)。
,字段和方法是等价的
All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation
在 Scala 中查看有关 how it's implemented 的更多信息。
P.S。 Scala 中的 UAP 似乎是 not completely implemented
在 'Effective Scala' 的 Laziness 部分,它说:
Fields in scala are computed by need when val is prefixed with lazy. Because fields and methods are equivalent in Scala (lest the fields are private[this])
'fields'和'methods'等价是什么意思?是不是比较强硬的说法?
主要原因可能是,lazy val
和 def
在使用之前计算(而不是在首次定义时)。
不同之处在于 lazy val
试图避免重新评估不变的值,这增加了将计算值保存在内存中的成本。
嗯,这只是意味着您可以通过 def
定义抽象 val
,通过 val
定义抽象 def
。
例如
trait Server {
def port:Int
}
有一个抽象函数,即port
。您肯定可以使用 def
实现(或定义或覆盖)它,例如
object DefaultServer extends Server {
override def port: Int = 80
}
但在这种情况下,每次访问 port
都会导致根本不需要的函数应用程序(或方法调用)。出于这个简单的原因,Scala 为我们提供了使用值
def
的可能性
object DefaultServer extends Server {
override val port: Int = 80
}
这同样适用于抽象值。您可以使用相同的语法定义抽象值:
trait Server {
val port: Int
}
您可以使用 def
:
object DefaultServer extends Server {
override def port: Int = 80
}
稳定性
您可能想知道如果您用每次调用时给您不同值的 def
覆盖抽象 val
会发生什么。您会因为该项目是 val
而获得第一个计算值,还是每次调用它都会获得不同的值,因为实际实现是 def
.
例如:
object DefaultServer extends Server {
override def port: Int = scala.util.Random.nextInt()
}
幸运的是 Scala 编译器检测到这一点并抛出以下错误:
error: overriding value a in trait Server of type Int;
method a needs to be a stable, immutable value
override def port:Int = scala.util.Random.nextInt()
懒惰
当谈到懒惰时,这种统一的行为(以相同的方式处理字段和方法)非常有用。
首先注意 lazy
抽象值不存在,即你不能将抽象 val
定义为 lazy
.
另一方面,通过 lazy val
实现抽象 def
是完全合法且有用的。 lazy
值将仅在第一次调用时计算并记忆(缓存并用于以后的调用)。
All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation
在 Scala 中查看有关 how it's implemented 的更多信息。
P.S。 Scala 中的 UAP 似乎是 not completely implemented