How are lazy val class variables implemented in Scala 2.10?

后端 未结 2 1992
名媛妹妹
名媛妹妹 2020-12-06 00:44

This answer to What\'s the (hidden) cost of Scala\'s lazy val? shows how they were implemented in Scala 2.7. But as the comments say, this must have changed since then, so I

2条回答
  •  长情又很酷
    2020-12-06 01:18

    Update Scala 2.12.1 (Dec. 2016, three years later).

    After PR 5294 (Fields phase fully expands lazy vals and modules), you can read in commit 743f0d2:

    Lazy val without local.

    Now synchronized is erased specially to avoid boxing, we can drop that work around.

    Note that this does add an extra cast and getter call on the slow path, but that likely doesn't matter.

    class C { def foo = {lazy val x = {println("a"); "A" }; x } }
    

    becomes:

    def foo(): String = {
      lazy  val x$lzy: scala.runtime.LazyRef[String] = new scala.runtime.LazyRef[String]();
    
       private def x$lzycompute(): String =
        x$lzy.synchronized[String]{
          if (x$lzy.initialized())
            x$lzy.value() // NOTE: gets an `.asInstanceOf[String]` after erasure
          else
            {
              x$lzy.value_=({
                scala.Predef.println("a");
                "A"
              });
              x$lzy.initialized_=(true);
              x$lzy.value() // NOTE: gets an `.asInstanceOf[String]` after erasure
            }
        }
    
      lazy def x(): String =
        if (x$lzy.initialized())
          x$lzy.value() // NOTE: gets an `.asInstanceOf[String]` after erasure
        else
          x$lzycompute();
    
      x()
    }
    

提交回复
热议问题