[英]Why implicit conversion doesn't work in Lists?
有人可以快速解釋為什么隱式轉換在這些情況下不起作用嗎? 謝謝。
scala> implicit def strTwoInt (s: String):Int = s.toCharArray.map{_.asDigit}.sum
strTwoInt: (s: String)Int
scala> List[Int]("1","2","3") sum
res3: Int = 6
scala> List("1","2","3") sum
<console>:9: error: could not find implicit value for parameter num: Numeric[java.lang.String]
List("1","2","3") sum
scala> val a = List("1","2","3")
scala> a.foldLeft(0)((i:Int, j:Int) => i+j)
<console>:10: error: type mismatch;
found : (Int, Int) => Int
required: (Int, java.lang.String) => Int
您的隱式轉換將字符串轉換為 Int。 在您的第一個示例中,它是由您嘗試將字符串放入 Ints 列表的事實觸發的。
在您的第二個示例中,您有一個字符串列表並調用方法 sum,該方法采用隱式Numeric[String]
。 您的轉換不適用,因為您既沒有嘗試在編譯器期望 Int 的地方傳遞 String,也沒有嘗試調用在 Int 而不是 String 中定義的方法。 在這種情況下,您可以定義一個明確使用您的轉換的Numeric[String]
,或者使用一個將List[Int]
作為參數的方法(向編譯器提供提示):
scala> def sumIt( xs: List[Int] ) = xs sum
sumIt: (xs: List[Int])Int
scala> sumIt( List("1","2","3") )
res5: Int = 6
在第三個示例中, foldLeft 第二個參數必須是以下類型:
(Int,String) => Int
您實際通過的類型是:
(Int,Int) => Int
但是,您沒有定義這兩種類型之間的任何隱式轉換。 但:
a.foldLeft(0)((i:Int, j:String) => i+j)
觸發您的轉換並起作用。
編輯:這是實現Numeric[String]
的方法:
implicit object StringNumeric extends math.Numeric[String] {
val num = math.Numeric.IntIsIntegral
def plus(x: String, y: String) = num.plus(x,y).toString
def minus(x: String, y: String) = num.minus(x,y).toString
def times(x: String, y: String) = num.times(x,y).toString
def negate(x: String): String = num.negate(x).toString
def fromInt(x: Int) = x.toString
def toInt(x: String) = x
def toLong(x: String) = toInt(x)
def toFloat(x: String) = toInt(x)
def toDouble(x: String) = toInt(x)
def compare(x:String,y:String) = num.compare(x,y)
}
scala> List("1","2","3") sum
res1: java.lang.String = 6
它有效,但結果是一個字符串。
這是一個快速解釋:隱式轉換適用於直接轉換的類型(例如,在您的情況下為String
和Int
),而不適用於任何參數化類型T[String]
或T[Int]
- 除非已定義隱式轉換對於T
本身,列表不是這種情況。
您的隱式轉換不適用於您的兩種情況(即使您有從List[String]
到List[Int]
的隱式轉換,它也不適用)。 僅當您需要Int
類型的值並且您正在傳遞String
時,它才會自動應用。 在這里,在第一種情況下,方法sum
要求一個Numeric[String]
隱式參數——從String
到Int
的隱式轉換在這里不起作用。
下一次嘗試的類似問題:您的收藏中的foldLeft
需要(Int, String) => Int
類型的 function 。 想象一下,如果基於從String
到Int
的隱式轉換,編譯器自動提供從(Int, Int) => Int
到(Int, String) => Int
的隱式轉換,我們將陷入混亂……
對於所有這些情況,修復它的簡單方法是事先在您的集合上顯式調用.map(stringToInt)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.