2012-01-30 22 views
17

piszę następujące niejawna konwersja w Scala:Dlaczego ten typ niejawnej konwersji jest nielegalny?

implicit def strToInt2(str: String):Int = { 
    str.toInt 
    } 

Ale wznosi ten błąd kompilacji:

<console>:9: error: type mismatch; 
found : str.type (with underlying type String) 
required: ?{val toInt: ?} 
Note that implicit conversions are not applicable because they are ambiguous: 
both method augmentString in object Predef of type (x: String)scala.collection. 
immutable.StringOps 
and method toi in object $iw of type (str: String)Int 
are possible conversion functions from str.type to ?{val toInt: ?} 
      str.toInt 
     ^

Jeśli usunąć typ zwracany, po prostu zadeklarować tak:

implicit def strToInt2(str: String) = { 
    str.toInt 
    } 

Kompiluje się pomyślnie. Czy ktoś może mi powiedzieć, jaka jest różnica między tymi dwoma?

+0

Nie znam dokładnej odpowiedzi, ale przypuszczam, że istnieje jeden niejawny ciąg konwersji -> int w Predef. Dodanie nowej konwersji tego typu powoduje, że są one niejednoznaczne. – dmitry

Odpowiedz

17

Ok, zacznijmy od początku, dlaczego to nie w pierwszym przypadku:

  1. spróbować zdefiniować niejawny sposób, który przekształca String się z Int i zrobić tak nazwać toInt.
  2. Niestety, toInt nie jest częścią klasy String. W związku z tym kompilator musi znaleźć ukrytą konwersję str w coś, co ma metodę toInt:Int.
  3. Na szczęście Predef.augmentString konwertuje String na StringOps, który ma taką metodę.
  4. Jednak typ Int również posiada taką metodę, a AS definiuje typ zwracany, dlatego metoda strToInt2 może być wywoływana rekurencyjnie, a ponieważ metoda jest niejawna, można ją zastosować do przekształcenia czegoś za pomocą funkcji toInt:Int.
  5. Kompilator nie wie, który niejawna metoda użyć (między ciebie i Predef.augmentString i zgłasza błąd.

W drugim przypadku, jak pominąć typ zwracany funkcja strToInt2 nie mogą być rekurencyjne i nie ma już dwóch kandydatów do przekształcenia String

ale jeśli po tej definicji, spróbować. "2".toInt, błąd jest z powrotem. masz teraz dwa sposoby, aby uzyskać coś z toInt:Int funkcji, gdy masz String

Powiązane problemy