簡體   English   中英

類型與類型參數不匹配

[英]Type mismatch with type parameters

我具有以下特征:

sealed trait Tree[+A]
case class Leaf[A](value: A) extends Tree[A]
case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]

然后,我定義一個類型為Branch的變量:

val t = Branch(Branch(Leaf("S"), Leaf(2)), Leaf(99))

上面的代碼工作正常。 但是當我將其更改為:

val t = Branch[Int](Branch(Leaf("S"), Leaf(2)), Leaf(99))

編譯器抱怨:

Error:(41, 37) type mismatch;
 found   : String("S")
 required: Int
    val t = Branch[Int](Branch(Leaf("S"), Leaf(2)), Leaf(99))

當我確定第一個Branch的類型(在這種情況下為Int)時,節點將是父節點固有的節點嗎?

此處發生的情況是,對於Branch(Leaf("S"), Leaf(2)) ,編譯器將嘗試查找公用類型。 對於IntString ,它們的超類型將是Any

問題是您正在使用Branch[Int]強制分支定義中的類型,該類型已由所包含的Branch[Any]無效。 刪除[Int]將解決編譯錯誤,但最終將導致Branch[Any]

讓我們細分一下您的定義:

sealed trait Tree[+A]

這里的+表示類型A可以是協變的。 我不會深入介紹方差,因為有很多很好的文章對此進行了解釋(例如, 此處 )。 基本上,這意味着如果StringAny的子類型,則Tree[String]將是Tree[Any]的子類型。

case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]

首先讓我們注意到A在左側樹和右側樹中是如何出現的。 那么,當我們將兩棵具有不同類型的樹放入同一個分支時會發生什么呢?

val left  = Leaf(1)   // Tree[Int]
val right = Leaf("a") // Tree[String]
val tree  = Branch(left, right) // Tree[???]

由於A必須是在同一個leftright的值(這就是我們如何定義它),編譯器試圖解決這個問題。 因此它自問: IntString的第一種常見類型是什么?

       Any
        ^
       / \
      /   \
     /     \
AnyVal     AnyRef
   /         \
  Int       String
   \         /
       ...

這是Scala中的類型層次結構相當簡化。 這里有更好的說明。 因此, StringInt的常見超類型是Any ,這就是為什么您的樹將成為Tree[Any]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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