簡體   English   中英

scala:類型不匹配錯誤 - 找到T,必需字符串

[英]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)+運算符的唯一普遍用法是字符串連接,因此ab必須都是字符串(或自動轉換為字符串)才能使其有效。 您的參數化類型T不知道是String,因此無法編譯。

在第二個示例中,聲明類型為T ab變量不能轉換為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM