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

时间:2013-02-13 14:44:53

标签: scala types lazy-evaluation

正如问题标题所述,访问type成员的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

2 个答案:

答案 0 :(得分: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

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

答案 1 :(得分: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

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

scala> m1(lv1)
res6: Int = 3

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

在您的情况下,您只能使用randomNonSpaceCoordinate致电nonSpaces,将其作为参数传递一点毫无意义。