【问题标题】:Scala sealed trait as key on map throws mismatch errorScala 密封特征作为地图上的键会引发不匹配错误
【发布时间】:2016-06-28 11:13:21
【问题描述】:

有人能帮我理解为什么这不起作用吗? Scala 2.10 版

object ColorEnum {
  sealed trait Color
  case object Red extends Color
  case object Blue extends Color
  case object Green extends Color
}

创建一个接受 Color 作为 Key 和 String 作为 value 的 Map

val colorMap = mutable.HashMap[ColorEnum.Color, String]()

使用 ColorEnum 作为 Key 在 Map 上放置一个项目

colorMap.put(ColorEnum.Red, "Foo")

这会引发异常

error: type mismatch
found: ColorEnum.Red.type
required: ColorEnum.Color

根据我对这应该如何工作的理解,我一定遗漏了一些东西。

谢谢

【问题讨论】:

  • 我已经通过提供指向其他相关主题的链接以及如何使用案例类作为键的示例来更新我的答案。
  • 这是为我编译的。你确定这是你使用的代码吗?
  • 如果我在object ColorEnum 层次结构之外定义特征和案例对象。然后将映射定义为val colorMap = mutable.HashMap[Color, String](),它使用colorMap.put(Red, "Foo") 工作。然后在 ColorEnum 中创建密封特征 Color 和 case 对象不起作用(至少对我而言)。
  • 原来的代码在shell里面不行,但是在worksheet里面可以。很郁闷

标签: scala


【解决方案1】:

总结:
从 Scala 2.11 开始(以及所有之前版本的 Scala 回到 2.8)Map 的键是 Map[A, +B] 中的 A 类型。而且 Map 在指定键时不允许协方差;即注意 A 前面没有加号 (+)。

这是一个特定的 StackOverflow 答案,它解决了详细信息: https://stackoverflow.com/a/678637/501113

详情:
您的特征Color 是您定义Map 的类型。你定义了Color trait 的三个后代。然后,您尝试将Color 特征的这些后代(而不是特征本身的实例)插入Map。而Map 的类型定义只允许Color trait 的直接实例,而不是后代(通过extendswith 定义)。

您可以在将后代键插入Map 时使用.asInstanceOf[Color],以符合Map 对键的类型要求。但是,请注意,使用这种方法被认为是不良代码气味。

奖励:
您似乎正在尝试定义自己的强类型枚举。请看this answer to a related question regarding defining enumerations in Scala

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-17
    • 2016-05-17
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    相关资源
    最近更新 更多