2012-03-07 24 views
6

miałem dziwny błąd wczoraj, że w końcu sprowadza się do następującego kodu:Nieoczekiwane zachowanie z implicits

Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_29). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> class X extends Function[String, Int] { def apply(x: String) = Integer.parseInt(x) } 
defined class X 

scala> implicit val x = new X 
x: X = <function1> 

scala> "56"/2 
res2: Int = 28 

Spodziewam to wyjątek, ponieważ String nie ma metody /. Zamiast tego Scala traktowała domyślną zmienną jako metodę niejawną (ponieważ implementuje ona Function[String,Int]) i przekształciła ciąg "56" w liczbę całkowitą 56.

Jak to działa? Opierając się na regułach wyszukiwania niejawnego, nie sądziłem, że uwzględniane będą niejawne zmienne, które działają jako funkcje.

+1

Dobra wiadomość, dzięki. – Odomontois

+0

W rzeczywistości, konwersja 'niejawna def' działa, ponieważ jest automatycznie przekształcana na wartość funkcji (to _eta rozszerzenie_). –

Odpowiedz

7

Semantyka niejawnych konwersji jest dokładnie tym, co zaobserwowałeś. Jeśli zdefiniować niejawna konwersja za pomocą metody niejawnej,

trait A 
trait B 

implicit def aToB(a : A) : B = new B {} 

zobaczysz, że masz teraz niejawny wartość funkcji A => B,

scala> implicitly[A => B] 
res1: A => B = <function1> 

A gdzie masz metodę związaną z myślą,

def foo[T <% B](t : T) : B = t 

jest równorzędny

def foo[T](t : T)(implicit conv : T => B) : B = conv(t) 

tj. niejawny argument odpowiadający powiązaniu widoku ma dokładnie taką samą postać, jak niejawna wartość funkcji generowana przez definicję metody niejawnej.

+0

Czy więc metody niejawne są zredukowane do zmiennych niejawnych typu Function? Lub Scala właśnie obsługuje oba przypadki? – Bill

+1

W każdym kontekście, w którym metoda musi być reifikowana jako wartość funkcji (która obejmuje aplikacje obejmujące ograniczenia widoku), tak. W moim przykładzie, jeśli właśnie zrobiłeś (nowy A {}: B), metoda byłaby zastosowana bez tworzenia obiektu funkcji, ale mechanizm jest identyczny, stąd zachowanie, które zaobserwowałeś. –

Powiązane problemy