我想定义一个方法参数化类型T
具有取决于什么隐式参数可以找到Box[T]
类型的行为。以下代码将此方法定义为foo
。当与foo[Int]
或foo[String]
呼叫时,将按照预期返回1
或"two"
。为什么Scala的类型推理失败,这组隐式参数涉及参数化类型?
凡事情变得怪异的是方法栏。它被定义为返回一个Int
,而不是foo[Int]
我只是foo
。我的希望是,编译器会推断T
必须是Int
。它不这样做,而是失败:
bash $ scalac Code.scala
Types.scala:15: error: ambiguous implicit values:
both value one in object Main of type => Main.Box[Int]
and value two in object Main of type => Main.Box[java.lang.String]
match expected type Main.Box[T]
def bar: Int = foo
^
one error found
是什么导致此错误?用foo[Int]
替换foo
编译得很好。更简单的情况下,没有Box[T]
类型也编译好。该示例也在下面,并使用argle
和bargle
而不是foo
和bar
。
object Main extends Application {
case class Box[T](value: T)
implicit val one = Box(1)
implicit val two = Box("two")
def foo[T](implicit x: Box[T]): T = {
x.value
}
// does not compile:
// def bar: Int = foo
// does compile
def bar: Int = foo[Int]
println(bar)
// prints 1
// the simpler situation where there is no Box type
implicit val three = 3
implicit val four = "four"
def argle[T](implicit x: T): T = x
def bargle: String = argle
println(bargle)
// prints "four"
}
在这段代码中发生了什么事情导致了这种行为?隐式参数,类型推断和擦除的这种相互作用是如何引起问题的?有没有办法修改这个代码,使得行def foo: Int = bar
有效?
我之前没有使用上下文边界。我不确定这是否符合我的实际情况,但它肯定是一个值得注意的有趣工具。 – toddaaro
我试图争取上下文边界来获得我想要的行为,但无法做到。我的主要目标是使得'foo'只要能被推断就不需要指定'T'。虽然上下文边界似乎比第二个参数列表更清洁。 – toddaaro