我有一个数字包装器,像这样
class NumWrapper[A<:AnyVal](var v: A)(implicit n:Numeric[A]) {
def +(other: A): NumWrapper[A] = {
new NumWrapper(n.plus(v, other))
}
def -(other: A): NumWrapper[A] = {
new NumWrapper(n.minus(v, other))
}
}
一切正常。但是当我想要隐式转换时,我创建了一个同伴类,如下所示:
object NumWrapper {
implicit def toNumWrapper[A<:AnyVal](v: A) = new NumWrapper[A](v)
}
但是我在编译时出现了错误:
无法找到参数n的隐式值:Numeric[A]
怎么了?为什么它试图在编译时找到类型A的隐式匹配?
非常感谢你的帮助。Scala中的隐式检查在编译时执行(它是一种静态类型语言)。如果编译器不能识别一个单一的,明确的,匹配的隐式值,它将在调用位置可用,它报错。
解决这个问题的一种方法是将隐式需求添加到toNumWrapper方法:object NumWrapper {
implicit def toNumWrapper[A<:AnyVal](v: A)(implicit n:Numeric[A]) = new NumWrapper[A](v)
}
这将隐式数字的需求推到需要隐式转换的位置,例如,在控制台中,我可以这样写:
scala> val chk1 = 3L
chk1: Long = 3
scala> val chk2 = NumWrapper.toNumWrapper(chk1)
chk2: NumWrapper[Long] = NumWrapper@1e89017a
编译器很高兴,因为(我认为-不完全确定)Long值携带自己的隐式数值[Long]。
根据您的代码,
class NumWrapper[A<:AnyVal](var v: A)(implicit n:Numeric[A])
调用new NumWrapper[MyType](v)
a Numeric[MyType]
必须在隐式解析范围内。
所以当你有
object NumWrapper {
implicit def toNumWrapper[A<:AnyVal](v: A) = new NumWrapper[A](v)
}
调用NumWrapper
构造函数,则必须解析Numeric[A]
。如果不是这样,编译器会抛出上述错误。