2016-09-23 5 views
3

Я не совсем понимаю, следующий код:Scala неявный метод аргумент устранения неоднозначности

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?

+3

Поскольку информация о типе Seq [A] доступна во время компиляции, чтобы вызвать правильный метод, но эта информация недоступна во время выполнения – Falmarri

+2

Не ответ на ваш вопрос, а интересное наблюдение: вы также можете устранить двусмысленность сделав одну функцию 'm()' a и оставив ее как метод. Никаких имплицитов или маркеров не требуется. – jwvh

ответ

0

Чтобы ответить на ваш вопрос напрямую, нет, стирание типа еще не произошло. Неявный поиск должен происходить с полным знанием типов. Чтобы увидеть, как эти методы выглядят во время выполнения, вы можете запустить 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 
} 

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

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

Смежные вопросы