scala之Scala 泛型实现的奇怪错误
zdz8207
阅读:62
2024-12-31 21:38:35
评论:0
我有以下特点:
trait SomeTrait {
def doSomething[V](msg: Message[V]): Message[V]
}
Message[V] 是一个案例类,如下所示:
case class Message[V](elems: Map[String, V])
我现在有一个调用 doSomething 方法的方法,如下所示:
val someWork = new SomeTrait {
override def doSomething[Int](msg: Message[Int]): Message[Int] = {
msg.copy(elems = msg.elems.map {
case (k, v) => (k, v + 1) // It fails here!!!
})
}
}
我收到一个奇怪的编译器错误:
Error:(16, 32) type mismatch;
found : Int(1)
required: String
Error occurred in an application involving default arguments.
case (k, v) => (k, v + 1)
我是不是哪里傻了?
请您参考如下方法:
注意:您的 Int
不是 scala Int
。您将 Scala Int
隐藏在泛型类型名称后面 - 您编写的内容看起来像是 C++ 中的模板特化,但泛型在 Scala 中不会以这种方式工作。当您在代码中将 [Int]
替换为 [XXX]
时,您将遇到相同的错误。
重写方法时不能更改类型签名。由于 trait promise 您可以不受任何限制地接受任何类型 V
,因此实现需要满足这一 promise 。
可以使用 type classes 实现类似 C++ 的特化- 你通过 promise 你将根据需要提供专门的实现来扩展你的契约(Contract):
case class Message[V](elems: Map[String, V])
trait SomeTrait {
def doSomething[V: MapValue](msg: Message[V])
}
trait MapValue[V] {
def map(v: V): V
}
implicit object MapValueInt extends MapValue[Int] {
def map(v: Int) = v + 1
}
val someWork = new SomeTrait {
override def doSomething[X: MapValue](msg: Message[X]) = {
val evidence = implicitly[MapValue[X]]
msg.elems.map {
case (k, v) => k -> evidence.map(v)
}
}
}
声明
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。