加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么要在Scala的块内转发引用的值是懒惰的?

发布时间:2020-12-16 19:02:44 所属栏目:安全 来源:网络整理
导读:The scope of a name introduced by a declaration or definition is the whole statement sequence containing the binding. However,there is a restriction on forward references in blocks: In a statement sequence s[1]...s[n] making up a block,if

The scope of a name introduced by a declaration or definition is the
whole statement sequence containing the binding. However,there is a
restriction on forward references in blocks: In a statement sequence
s[1]...s[n] making up a block,if a simple name in s[i] refers to
an entity defined by s[j] where j >= i,then for all s[k]
between and including s[i] and s[j],

  • s[k] cannot be a variable definition.
  • If s[k] is a value definition,it must be lazy.

编辑:我不确定Mika?lMayer的答案实际上解释了一切.考虑:

object Test {
  def main(args: Array[String]) {
    println(x)
    lazy val x: Int = 6
  }
}

在这里,懒惰值x必须在代码中实际定义之前被读取/评估!这与Mika?l的这样的说法相矛盾:懒惰的评估消除了在定义之前对事物进行评估的需要.

解决方法

通常你不能这样做:

val e: Int = 2
val a: Int = b+c
val b: Int = c
val c: Int = 1
val d: Int = 0

因为在定义a时没有定义值c.因为引用c,所以a和c之间的所有值应该是懒惰的,以避免依赖

val e: Int = 2
lazy val a: Int = b+c
lazy val b: Int = c
lazy val c: Int = 1
val d: Int = 0

这实际上是将a,b和c转换成对象,其值在被读取时被初始化,这将在声明之后,即这将等价于:

val e: Int = 2
var a: LazyEval[Int] = null
var b: LazyEval[Int] = null
var c: LazyEval[Int] = null
a = new LazyEval[Int] {
  def evalInternal() = b.eval() + c.eval()
}
b = new LazyEval[Int] {
  def evalInternal() = c.eval()
}
c = new LazyEval[Int] {
  def evalInternal() = 1
}
val d = 0

其中LazyEval将类似于以下内容(由编译器本身实现)

class LazyEval[T] {
  var value: T = _
  var computed: Boolean = false
  def evalInternal(): T // Abstract method to be overriden
  def eval(): T = {
     if(computed) value else {
       value = evalInternal()
       computed = true
       value
     }
  }
}

编辑

在java中并不存在vals.它们是局部变量,也不存在于计算中.因此,在任何事情完成之前都存在惰性声明的声明.并记住关闭在Scala中实现.
你的块将被重写:

  object Test {
    def main(args: Array[String]) {
      // Declare all variables,val,vars.
      var x: Lazy[Int] = null
      // No more variables to declare. Lazy/or not variable definitions
      x = new LazyEval[Int] {
        def evalInternal() = 6
      }
      // Now the code starts
      println(x)
    }
  }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读