懒加载隐式值未找到。

7
为什么Scala找不到这里的隐式值?
class A

class Foo {
  lazy val x = implicitly[A]
  implicit lazy val a = new A
}

错误:无法找到参数e的隐式值

但是这个例子完全正常:

class Foo {
  lazy val x = implicitly[A]
  implicit lazy val a: A = new A // note explicit result type
}

定义了一个名为Foo的类

顺便提一下,我在这个应用程序中卡在Scala 2.10上。此外,用def替换lazy val似乎并没有改变任何东西。

在我的实际应用程序中,我有一个文件,其中定义了许多隐式对象,这些对象是针对各种域对象定义的,其中一些依赖于彼此。尝试安排它们以确保所有依赖项都在其相应的依赖项之前似乎像是一场噩梦,因此我将它们全部标记为lazy。不得不显式声明每个这些val的类型会使代码变得混乱,并且似乎是不必要的。有没有办法解决这个问题?


这也发生在Scala2.11中。正如你所说,正确的顺序确实可以工作implicit lazy val a = new A; lazy val x = implicitly[A]。这不应该是Scala中的一个bug吗? - tuxdna
如果将隐式调用移动到隐式惰性值定义之后,则无需添加类型注释即可编译。 - Vered Rosen
1个回答

3

为什么Scala无法找到隐式转换?

我已经实现了一个稍微宽松一点的规则:没有显式结果类型的隐式转换只在其自身定义之后的文本中可见。这样,我们可以避免循环引用错误。我暂时关闭,看看这个方法是否有效。如果还有问题,我们可能会回到这个问题上来。

对于隐式转换,我仍然建议这样做。这个问题不是唯一的原因;如果将来隐式的类型意外更改,这可能以难以理解的方式破坏编译。另请参阅上面链接的问题:

马丁在scala-user列表上写道:“一般来说,为隐式方法编写结果类型总是一个好主意。也许语言应该要求这样做。”我自己也被一些问题咬了几次,一旦我为一个隐式方法添加了结果类型,问题就消失了,所以我想在这个问题上开个票。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接