加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala:隐式参数中的错误

发布时间:2020-12-16 09:54:27 所属栏目:安全 来源:网络整理
导读:以下是我真正问题的简化版本: class Z[T]object E extends Enumeration { implicit val z = new Z[Value] val X,Y = Value}implicit def f[T : Z] = (getter: T) = 0implicit def o[T](v: Option[T])(implicit toInt: T = Int) = 0def e: Option[E.Value] =
以下是我真正问题的简化版本:

class Z[T]
object E extends Enumeration {
  implicit val z = new Z[Value] 
  val X,Y = Value
}
implicit def f[T : Z] = (getter: T) => 0
implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0
def e: Option[E.Value] = null
val b: Int = e

这是有效的,b隐式转换为o(e)(f(E.z)).但随着以下小变化:

implicit def f[T : Z] = (setter: T => Unit) => 0
implicit def o[T](v: Option[T])(implicit toInt: (T => Unit) => Int) = 0

它找不到合适的隐含值E.z虽然与原始代码没有本质区别,但是手动显式转换为o(e)(f(E.z))仍然有效.

我知道隐式参数的实现还没有完成,还有很多未解决的问题.如果这是其中之一,我想向Scala贡献者报告.所以我的问题是,a)这真的是一个错误吗? b)如果是这样,我在哪里以及如何提交错误以便将来修复?

UPDATE

特拉维斯的回答就像一个魅力!顺便说一下,上面的代码解决了我原来的问题:

implicit object E extends Enumeration { val X,Y = Value }
implicit object F extends Enumeration { val X,Y = Value }
implicit def f[T <: Enumeration](getter: T#Value)(implicit e: T) = 0
implicit def o[T](v: Option[T])(implicit toInt: T => Int) = 0
val b: Int = Some[E.Value](null)

在这段代码中,情况恰恰相反:它适用于setter版本,但不适用于更简单的getter版本.编译器抱怨说使用E或F作为隐式参数是令人困惑的,尽管使用F实际上并不编译也没有意义.我通过做类似的事情设法让它工作:

implicit def f[S <% T => T,T <: Enumeration](getter: T#Value)(implicit e: T) = 0

这是有效的,虽然我不知何故可以使它工作,但我仍然不理解这种魔法背后的逻辑.

解决方法

你已经遇到了另一个 this limitation Scala类型推理系统的变种.

如果在第一种情况下,编译器将解析T的f,它正在寻找从普通旧E.Value到Int的隐式转换,而不是在第二种情况下,它想要从E.Value =>转换.单位(即,Function1 [E.Value,Unit])到Int.

幸运的是,在这种情况下有一个简单的解决方法 – 只需使用视图绑定:

implicit def f[F <% T => Unit,T: Z] = (setter: F) => 0

这将是以下类似的东西:

implicit def f[F,T](implicit st: F <:< (T => Unit),ev: Z[T]) = (setter: F) => 0

现在当编译器想要从E.Value =>进行转换时单位到Int它将能够将F解析为E.Value =>单位立即然后T到E.Value.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读