Я хотел бы определить метод, параметризованный типом T
, поведение которого зависит от того, какой неявный аргумент можно найти для типа Box[T]
. В следующем коде этот метод определен как foo
. При вызове с foo[Int]
или foo[String]
он без проблем вернет 1
или "two"
, как и ожидалось.
Где все становится странным, так это в панели методов. Он определяется как возвращающий 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
на foo[Int]
компилируется нормально. Более простая ситуация, когда нет типа 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
работала?