[英]scala: type mismatch error - found T, required String
我正在學習scala,這個問題可能很愚蠢,但是......為什么?
例如,這沒關系:
def matchList(ls: List[Int]): List[Int] = ls match {
case 1 :: rest => rest
case a :: b :: rest => (a + b) :: rest
case _ => ls
}
matchList: (ls: List[Int])List[Int]
但是帶有類型參數的函數不能編譯:
def matchList[T](ls: List[T]): List[T] = ls match {
case 1 :: rest => rest
case a :: b :: rest => (a + b) :: rest
case _ => ls
}
<console>:10: error: type mismatch;
found : T
required: String
case a :: b :: rest => (a + b) :: rest
為什么?
對於任何類型T
,操作T + T
都沒有任何意義。 (所有類型都支持+
?不。想想添加兩只狗或兩名員工。)
在您的情況下,字符串連接運算符被調用(通過any2stringadd
pimp添加),其返回類型(顯然)為String
。 因此錯誤消息。
你需要的是指定類型的方式T
必須支持,你結合型的兩個值的操作T
得類型的新值T
。 斯卡拉茲的Semigroup
完全適合這個法案。
以下作品:
def matchList[T : Semigroup](ls: List[T]): List[T] = ls match {
case 1 :: rest => rest
case a :: b :: rest => (a |+| b) :: rest // |+| is a generic 'combining' operator
case _ => ls
}
我認為問題在於(a + b)
, +
運算符的唯一普遍用法是字符串連接,因此a
和b
必須都是字符串(或自動轉換為字符串)才能使其有效。 您的參數化類型T
不知道是String,因此無法編譯。
在第二個示例中,聲明類型為T
a
, b
變量不能轉換為String
,這是從程序推斷出的必需參數類型+
(即在沒有任何參數的情況下應用於+
的參數類型的視圖)其他信息)。
在第一個例子中,推理可以猜測要應用的右+
函數,考慮它將列表元素的類型作為參數,謝天謝地,你在類型聲明中提到這些元素的類型是Int
。 嘗試輸入
"1"+2
1 + 2
...在REPL中看看Scala嘗試做什么。 然后閱讀有關視圖 。
現在,我推測通過使用上面的類型參數T
,你試圖編寫一個適用於任何數字類型的函數,不是嗎? 在這種情況下,您可以使用Numeric
特征。 在建議以下內容之前,我會讓你閱讀有關含義的內容:
def matchList[T](ls: List[T])(implicit n:Numeric[T]): List[T] = {
import n.mkNumericOps
ls match {
case 1 :: rest => rest
case a :: b :: rest => (a + b) :: rest
case _ => ls
}}
你得到:
matchList(List(1,2,3))
res2: List[Int] = List(2, 3)
matchList(List(2,3,4))
res4: List[Int] = List(5, 4)
matchList(List(2.0,3.0,4.0))
res5: List[Double] = List(5.0, 4.0)
沒有任何導入:
def matchList[T](ls: List[T])(implicit wrapper:Numeric[T]): List[T] = ls match {
case 1 :: rest => rest
case a :: b :: rest => wrapper.plus(a, b) :: rest
case _ => ls
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.