我写了这段代码
trait Pet
case class Dog() extends Pet
case class Cat() extends Pet
def foo(i: Int)(implicit d: Dog) = println("dog")
def foo(i: Int)(implicit c: Cat) = println("cat")
def doFoo(a: Pet) = {
a match {
case a: Dog => implicit val dog : Dog = a; foo(10)
case a: Cat => implicit val cat : Cat = a; foo(10)
case _ => println("unknown")
}
}
我收到错误
cmd0.sc:8: ambiguous reference to overloaded definition,
both method foo in object cmd0 of type (i: Int)(implicit c: $sess.cmd0.Cat)Unit
and method foo in object cmd0 of type (i: Int)(implicit d: $sess.cmd0.Dog)Unit
match argument types (Int)
case a: Dog => implicit val dog : Dog = a; foo(10)
^
cmd0.sc:9: ambiguous reference to overloaded definition,
both method foo in object cmd0 of type (i: Int)(implicit c: $sess.cmd0.Cat)Unit
and method foo in object cmd0 of type (i: Int)(implicit d: $sess.cmd0.Dog)Unit
match argument types (Int)
case a: Cat => implicit val cat : Cat = a; foo(10)
但为什么感觉有歧义...因为在我的第一个案例匹配中有一个隐含的val狗,在我的第二个案例匹配中有一个隐含的val cat。所以它应该找到正确的含义。
为什么它没有正确解决?
我的环境是
Welcome to the Ammonite Repl 0.8.2
(Scala 2.12.1 Java 1.8.0_121)
^
答案 0 :(得分:4)
编译器仅使用第一个参数组来消除重载方法的歧义。
def foo(x:Int)(y:Long): Long = y
def foo(x:Int)(y:Short): Short = y
foo(9)(2L) // Error: ambiguous reference to overloaded definition
- 更新 -
您已经简化了代码示例,以至于很难说出您实际想要实现的目标。这会得到你之后的目标吗?
trait Pet {def foo(i: Int): Unit}
case class Dog() extends Pet {def foo(i: Int): Unit = println("dog")}
case class Cat() extends Pet {def foo(i: Int): Unit = println("cat")}
def doFoo(a: Pet) = a match {
case d: Dog => d.foo(10)
case c: Cat => c.foo(10)
case _ => println("unknown")
}
答案 1 :(得分:0)
@jwvh回答是正确答案。
按照Seth Tisue的建议,这里是使用类型类实现这个问题(假设我的要求是正确的):
trait Pet[A] {
def name: String
}
object Pet {
def create[A](n: String) = new Pet[A] { def name = n }
}
case class Dog()
object Dog {
implicit val dogIsPet = Pet.create[Dog]("dog")
}
case class Cat()
object Cat {
implicit val catIsPet = Pet.create[Cat]("cat")
}
def foo[A](i: A)(implicit p: Pet[A]) = p.name
然后你可以像这样使用foo:
@ foo(Dog())
res5: String = "dog"
@ foo(Cat())
res6: String = "cat"