2011-10-04 66 views
3

我試圖執行一些數量型和我打這個問題是'1 * BigInt(1)'如何工作,我該怎麼做?

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?

回答

7

我認爲你在你的Num類中缺少*方法,它接受一個Num作爲參數。

+0

好去處!我想我的例子太多了,確實如此。它看起來像我的實際問題是一個不同的,雖然有相同的錯誤信息... – soc

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)

+2

好的答案。有關implicits和scope的更多信息,請參閱[Daniel Sobral的詳細教程](http://stackoverflow.com/questions/5598085/where-does-scala-look-for-implicits)。 –

+1

是的,隱式範圍更改已經在2.9.1中。 – Debilski