繁体   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