有時在當(dāng)前作用域可能存在多個符合條件的隱含轉(zhuǎn)換,在大多數(shù)情況下,Scala 編譯器在此種情況下拒絕自動插入轉(zhuǎn)換代碼。隱含轉(zhuǎn)換只有在轉(zhuǎn)換非常明顯的情況下工作良好,編譯器只要例行公事插入所需轉(zhuǎn)換代碼即可。如果當(dāng)前作用域存在多個可選項,編譯器不知道優(yōu)先選擇哪一個使用。
scala> def printLength(seq:Seq[Int]) = println (seq.length)
printLength: (seq: Seq[Int])Unit
scala> implicit def intToRange(i:Int) = 1 to i
intToRange: (i: Int)scala.collection.immutable.Range.Inclusive
scala> implicit def intToDigits(i:Int) = i.toString.toList.map( _.toInt)
intToDigits: (i: Int)List[Int]
scala> printLength(12)
<console>:11: error: type mismatch;
found : Int(12)
required: Seq[Int]
Note that implicit conversions are not applicable because they are ambiguous:
both method intToRange of type (i: Int)scala.collection.immutable.Range.Inclusive
and method intToDigits of type (i: Int)List[Int]
are possible conversion functions from Int(12) to Seq[Int]
printLength(12)
這個例子產(chǎn)生的歧義是非常明顯的,將一個整數(shù)轉(zhuǎn)換成一組數(shù)字和轉(zhuǎn)換成一個序列是明顯兩個不同的變化。此時應(yīng)該明確指明使用那個變換:
scala> intToDigits(12)
res1: List[Int] = List(49, 50)
scala> printLength(intToDigits(12))
2
scala> printLength(intToRange(12))
12
在 Scala2.7 以前,Scala 編譯器碰到多個可選項時都這么處理,從 2.8 版本以后,這個規(guī)則不再這么嚴格,如果當(dāng)前作用域內(nèi)有多個可選項, Scala 編譯器優(yōu)先選擇類型更加明確的隱含轉(zhuǎn)換。 比如兩個隱含變換一個參數(shù)類型為 String,而另外一個類型為 Any。兩個隱含轉(zhuǎn)換都可以備選項時,Scala 編譯器優(yōu)先選擇參數(shù)類型為 String 的那個隱含轉(zhuǎn)換。
“更明確”的一個判斷規(guī)則如下:
Scala 做出這個改進的原因是為了更好的實現(xiàn) Java,Scala 集合類型(也包括字符串)之間的互操作性。