3

正如问题标题所述,访问成员是否typelazy 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

4

2 回答 2

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")

在您的情况下,您将只能调用randomNonSpaceCoordinatewith nonSpaces,这使得将其作为参数传递根本没有意义。

于 2013-02-13T15:04:38.563 回答
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。

于 2013-02-13T14:59:33.207 回答