访问延迟val的类型是否会导致它被评估?

ciu*_*can 3 types scala lazy-evaluation

由于问题的标题状态,并访问typeA的lazy val成员造成该成员的评价?或者它只是使用其静态类型?

这里是其中我有一个示例代码implicit lazy val,我想用它的在该方法中类型的接受implicit val与该类型:

implicit lazy val nonSpaces: Array[(Point, Part)]

...

def randomNonSpaceCoordinate(implicit nonSpaces: this.nonSpaces.type): Point = nonSpaces(Utils.Random.randUpTo(nonSpaces.length))._1

sen*_*nia 5

让我们来看看:

scala> object Test {
     |   lazy val test: String = {println("bang!"); "value"}
     |   val p: this.test.type = null
     |   def testDef(p: this.test.type) = println(p)
     | }
defined module Test

scala> Test.testDef(Test.p)
null

scala> Test.testDef(Test.test)
bang!
value
Run Code Online (Sandbox Code Playgroud)

因此,您可以看到只是访问该类型不需要实际评估惰性val.


Ran*_*ulz 5

不.类型级计算(除了它们的影子自我"反射")是编译时的事情.

你可以验证这样的事情:

scala> lazy val lv1 = { println("Initializing lv1"); "lv1" }
lv1: String = <lazy>

scala> def m1(s: lv1.type): Int = s.length
m1: (s: lv1.type)Int

scala> lv1
Initializing lv1
res5: String = lv1
Run Code Online (Sandbox Code Playgroud)

但是,您可能需要更仔细地考虑使用.type这样的方法,因为它是所谓的路径依赖类型,在这种情况下,它可能太窄而无法使用:

scala> m1(lv1)
res6: Int = 3

scala> m1("42")
<console>:10: error: type mismatch;
 found   : String("42")
 required: lv1.type
              m1("42")
Run Code Online (Sandbox Code Playgroud)

在你的情况,你只能够调用randomNonSpaceCoordinatenonSpaces,使得它有点毫无意义,它作为参数传递的.

  • 这是我的观点.它是`String`,它是`nonSpaces`的类型_specifically_和没有其他`String`.因此,术语"路径依赖型". (2认同)