Скала неявный метод аргумент устранения неоднозначности
Я не совсем понимаю следующий код:
object M {
implicit object AMarker
implicit object BMarker
def m(ints: Seq[Int])(implicit i: AMarker.type ): Unit = {
println(s"int seq $ints");
}
def m(strs: Seq[String])(implicit s: BMarker.type ): Unit = {
println(s"string seq $strs")
}
}
import M._
m(Seq(1, 2, 3))
m(Seq("a", "b", "c"))
Если бы не два маркера, он не скомпилируется, потому что два m
методы имеют одинаковую сигнатуру после стирания типа.
Тем не менее, я не понимаю, что такое "магия", которая связывает AMarker
к Seq[Int]
, а также BMarker
в Seq[String]
,
Конкретнее, когда я звоню m(Seq("a", "b"))
как компилятор знает, что он должен использовать неявное BMarker
и позвони второму m
? Не имеет Seq
уже стерли тип?
1 ответ
Чтобы ответить на ваш вопрос напрямую, нет, тип удаления еще не произошел. Неявный поиск должен происходить с полным знанием типов. Чтобы увидеть, как эти методы выглядят во время выполнения, вы можете запустить javap
чтобы увидеть скомпилированные классы:
scala> :javap M -s
Compiled from "<console>"
public class M$ {
public static final M$ MODULE$;
Signature: LM$;
public static {};
Signature: ()V
public void m(scala.collection.Seq<java.lang.Object>, M$AMarker$);
Signature: (Lscala/collection/Seq;LM$AMarker$;)V
public void m(scala.collection.Seq<java.lang.String>, M$BMarker$);
Signature: (Lscala/collection/Seq;LM$BMarker$;)V
public M$();
Signature: ()V
}
В общем, компилятор сделал однозначные методы времени выполнения. Он ищет точный метод во время компиляции и по существу использует неявный объект для устранения неоднозначности.
Крутой трюк Кстати Я не видел, чтобы это использовалось прямо таким образом раньше.