Скала неявный метод аргумент устранения неоднозначности

Я не совсем понимаю следующий код:

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
}

В общем, компилятор сделал однозначные методы времени выполнения. Он ищет точный метод во время компиляции и по существу использует неявный объект для устранения неоднозначности.

Крутой трюк Кстати Я не видел, чтобы это использовалось прямо таким образом раньше.

Другие вопросы по тегам