'1*BigInt(1)'如何工作?我怎么能这样做?

soc*_*soc 3 math scala numeric implicit

我尝试实现一些数字类型,我遇到了问题

mynum * 1
Run Code Online (Sandbox Code Playgroud)

有效,但不是

1 * mynum
Run Code Online (Sandbox Code Playgroud)

我试图定义这样的隐式转换

case class Num(v: Int) {
  def * (o: Int) = new Num(v*o)
}

implicit def int2Num(v: Int) = Num(v)
Run Code Online (Sandbox Code Playgroud)

但它似乎不起作用,因为我总是得到以下错误:

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)
                ^
Run Code Online (Sandbox Code Playgroud)

另一方面

1 * BigInt(1)
Run Code Online (Sandbox Code Playgroud)

虽然我在查看代码时无法确定解决方案,但仍然有办法.

使其运作的机制是什么?

编辑:我用我遇到的实际问题创建了一个新问题,为什么在这种情况下不考虑使用泛型参数的隐式转换?.

ret*_*nym 9

当应用程序a.meth(args)失败时,编译器会从a具有该方法的内容中搜索隐式视图meth.任何符合的隐含值或方法A => { def meth(...) }都可以.如果找到一个,则将代码重写为view(a).meth(args).

它看起来在哪里?首先,它查看当前范围,由本地定义的含义和导入的含义组成.

(实际上存在搜索的第二阶段,其中考虑了带有名称参数的转换方法,但这对于这个答案并不重要.)

如果失败,则查看隐式范围.这包括我们正在搜索的类型的"部分"的伴随对象.在这种情况下,我们正在追求A => { def meth(...) },所以我们只看一下A(及其超类型)的伴随对象.

在Scala主干中,隐式范围扩展了一小部分,以包括参数类型的伴随对象.不确定这是否已经在2.9.1中,也许友好的读者会为我解决这个问题并更新这个答案.

所以1 + BigInt(2)扩展到了BigInt.int2bigInt(1) + BigInt(2)

  • 很好的答案.有关含义和范围的更多信息,请参阅[Daniel Sobral的详细教程](http://stackoverflow.com/questions/5598085/where-does-scala-look-for-implicits). (2认同)

Jen*_*der 7

我认为你在Num类中缺少*方法,它接受Num作为参数.