在下面的示例中,似乎
Scala编译器仅在识别为隐式类时才识别Wrapper的高级表示.这是为什么?
scala> case class nested(n: Int) defined class nested scala> case class Wrapper[A <: Product](nested: A) defined class Wrapper scala> implicit class I1[W <: Wrapper[A],A <: Product](underlying: W) { | def ok1() = true | } defined class I1 scala> Wrapper(nested(5)).ok1() <console>:26: error: value ok1 is not a member of Wrapper[nested] Wrapper(nested(5)).ok1() ^ scala> implicit class I2[W <: Wrapper[_]](underlying: W) { | def ok2() = true | } defined class I2 scala> Wrapper(nested(5)).ok2() res1: Boolean = true
隐式解决方案是否有一个解决方法来维护有关嵌套类型的完整信息,允许将类型类证据(例如TypeTag)附加到它上面?
注意:上面的示例显示nested和Wrapper是案例类,但这不是问题的组成部分.它只是为更短更简单的控制台会话提供便利.
解决方法
由于Scala类型推断的限制,这种情况正在发生.见
SI-2272.
隐式无法解析,因为编译器无法正确推断A.如果我们启用-Xlog-implicits,我们可以看到这一点.请注意,A被推断为nothing:
I1 is not a valid implicit value for Test.w.type => ?{def ok: ?} because: inferred type arguments [Wrapper[nested],nothing] do not conform to method I1's type parameter bounds [W <: Wrapper[A],A <: Product]
如果我们尝试手动实例化I1,会发生同样的事情:
scala> val w = Wrapper(nested(5)) w: Wrapper[nested] = Wrapper(nested(5)) scala> new I1(w) <console>:21: error: inferred type arguments [Wrapper[nested],nothing] do not conform to class I1's type parameter bounds [W <: Wrapper[A],A <: Product] new I1(w) ^ <console>:21: error: type mismatch; found : Wrapper[nested] required: W new I1(w) ^
现在,解决方法.
首先,Wrapper是一个案例类,因此它没有理由让它有子类型.您可以删除W类型参数,并将底层更改为Wrapper [A]:
implicit class I1[A <: Product](underlying: Wrapper[A]) { def ok = true }
如果您仍然希望需要两个类型参数,您还可以要求隐含证据表明W<:<包装器[A],同时删除类型参数W的上限:
implicit class I1[W,A <: Product](underlying: W)(implicit ev: W <:< Wrapper[A]) { def ok = true }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。