我尝试实现一些数字类型,我遇到了
的问题mynum * 1
有效,但不是
1 * mynum
我尝试定义像这样的隐式转换
case class Num(v: Int) {
def * (o: Int) = new Num(v*o)
}
implicit def int2Num(v: Int) = Num(v)
但它似乎不起作用,因为我总是得到以下错误:
scala> 1 * new Num(2)
<console>:14: error: overloaded method value * with alternatives:
(x: Double)Double <and>
(x: Float)Float <and>
(x: Long)Long <and>
(x: Int)Int <and>
(x: Char)Int <and>
(x: Short)Int <and>
(x: Byte)Int
cannot be applied to (Num)
1 * new Num(2)
^
另一方面
1 * BigInt(1)
有效,所以必须有办法,但在查看代码时我无法确定解决方案。
使它运作的机制是什么?
编辑:我根据我遇到的实际问题Why is the implicit conversion not considered in this case with generic parameters?创建了一个新问题。
答案 0 :(得分:9)
当应用程序a.meth(args)
失败时,编译器会搜索从a
到具有方法meth
的隐式视图。任何符合A => { def meth(...) }
的隐式值或方法都可以。如果找到,则代码将重写为view(a).meth(args)
。
它在哪里?首先,它查看当前范围,由本地定义的含义和导入的含义组成。
(实际上是搜索的第二阶段,其中考虑了带有名称参数的转换方法,但这对于这个答案并不重要。)
如果失败,则查看隐式范围。这包括我们正在搜索的类型的“部分”的伴随对象。在这种情况下,我们在A => { def meth(...) }
之后,所以我们只看A
的伴随对象(及其超类型)。
在Scala主干中,隐式作用域为extended a tiny bit,以包含类型的参数的伴随对象。不确定是否已经在2.9.1中,也许友好的读者会为我解决这个问题并更新这个答案。
因此1 + BigInt(2)
已扩展为BigInt.int2bigInt(1) + BigInt(2)
答案 1 :(得分:7)
我认为你在Name类中缺少*方法,它接受一个Number作为参数。