簡體   English   中英

從案例類中提取Map鍵類型為什么不起作用?

[英]Why does not Map key type work when extracted from a case class?

在以下代碼中,可以直接使用map鍵,也可以將其存儲在val ,但不能將其存儲在case class

sealed trait FooKey
case object KeyA extends FooKey
case object KeyB extends FooKey

case class KaseKey(key:FooKey)

object Main extends App {
  val m = Map(KeyA -> "A", KeyB -> "B")


  val kk = KaseKey(KeyA)
  val kv = KeyA

  m(KeyA) // works
  m(kv) // works
  m(kk.key) // error: found: Main.kk.key.type (with underlying type FooKey)
}

最后一行顯示的完整錯誤是:

錯誤:(16,8)類型不匹配;

找到:Main.kk.key.type(具有基礎類型FooKey)

必需:具有FooKey可序列化的產品

這是什么原因呢? 為什么密鑰不再被接受並且一旦存儲在case class就無法進行類型檢查?

這是因為以下行推斷出了密鑰的類型:

val m = Map(KeyA -> "A", KeyB -> "B")

如果您查看REPL,它將告訴您它看到Map[Product with Serializable with FooKey,String] 這是因為KeyAKeyB的常見超類型就是這樣。 案例類為您提供了Product特質,該特質允許對product元素進行迭代,定義equalshashCode

因此,您應該注釋地圖:

val m = Map[FooKey, String](KeyA -> "A", KeyB -> "B")

或者,您定義

sealed trait FooKey extends Product with Serializable

正如0__ 的答案所解釋 ,這是因為將case objects用作映射鍵的結果是, m的類型不是FooKey而是Product with Serializable with FooKey

可以通過使用普通objects而不是case objects來避免這種case objects

sealed trait FooKey
object KeyA extends FooKey
object KeyB extends FooKey

一個可能的缺點是使用了默認的Java對象hashCode ,它可能比case objects提供的默認值更不合理。

暫無
暫無

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

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