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) 
    } 
  } 
} 


标签:Scala
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号