【问题标题】:Ambiguous Implicit Values for Case Class Option Parameter案例类选项参数的模糊隐含值
【发布时间】:2020-07-01 14:45:13
【问题描述】:

我正在做一些我发明的关于案例类和类型类的练习。我遇到的问题之一如下:

object Example extends App {

  sealed trait Serializer[T] {
    def serialize(seq: List[T]): String
  }

  implicit object StringSerializer extends Serializer[String] {
    def serialize(seq: List[String]): String = seq.toString()
  }

  implicit object IntSerializer extends Serializer[Int] {
    def serialize(seq: List[Int]): String = seq.toString()
  }

  case class Marker[T: Serializer](lst: Option[List[T]] = None)
  
  Marker() // ambiguous implicit values: here...
}

现在这给出了一个关于模糊隐含值的错误。我认为这与我之前提出的一个问题有关(尽管错误消息不同):

Type erasure in a nested list with a given context bound

我是否正确,即使错误消息不同,这里的工作过程也是一样的?

【问题讨论】:

  • 你希望你的 Marker 实例用于什么,Int 还是 List?
  • 我希望标记可以是 Int 或 List,并且只有当用户传入列表时才会设置类型。 In my mind I assumed the compiler would just not bother when the option was equal to None.
  • 好吧,lst 字段是不可变的,所以以后任何人都无法传递不同的列表

标签: scala types optional typeclass


【解决方案1】:

编译器无法推断T。尝试明确指定T

Marker[String]() // compiles
Marker[Int]() // compiles

当您提供lst 时,它可以推断出T 本身

Marker(Some(List(1, 2)))
Marker(Some(List("a", "b")))

出于同样的原因

Marker(Option.empty[List[Int]])
Marker(Option.empty[List[String]])
Marker[Int](None)
Marker[String](None)
Marker(None: Option[List[Int]])
Marker(None: Option[List[String]])

Marker(None) 不编译时编译。

或者你可以优先考虑你的隐含

trait LowPrioritySerializer {
  implicit object StringSerializer extends Serializer[String] {
    def serialize(seq: List[String]): String = seq.toString()
  }
}

object Serializer extends LowPrioritySerializer {
  implicit object IntSerializer extends Serializer[Int] {
    def serialize(seq: List[Int]): String = seq.toString()
  }
}

如果IntSerializer 不起作用(如果类型不同),则首先尝试IntSerializer,然后再尝试StringSerializer

【讨论】:

  • 啊哈我现在明白了。谢谢!!
猜你喜欢
  • 1970-01-01
  • 2011-07-15
  • 1970-01-01
  • 2014-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多