以下是我真正问题的简化版本:
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(Ez))。但有以下小的变化:
implicit def f[T : Z] = (setter: T => Unit) => 0
implicit def o[T](v: Option[T])(implicit toInt: (T => Unit) => Int) = 0
尽管与原始代码没有本质区别,但它未能找到适当的隐式值 Ez,而手动显式转换为 o(e)(f(Ez)) 仍然有效。
我知道隐式参数的实现还没有完成,还有很多未解决的问题。如果这是其中之一,我想向 Scala 贡献者报告。所以我的问题是,a) 这真的是一个错误吗?b) 如果是这样,我可以在哪里以及如何提交错误以便将来修复?
更新
特拉维斯的回答就像一个魅力!顺便说一句,上面的代码是我原来问题的解决方法:
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
这行得通,虽然我能以某种方式让它工作,但我仍然不明白这个魔法背后的逻辑。