2013-02-27 8 views

Odpowiedz

132

Jest kilka rzeczy.

Po pierwsze, Scala pozwala pominąć kropki i pareny z wielu wywołań metod, więc 20 seconds jest równoważne 20.seconds() *.

Po drugie, stosowana jest "konwersja niejawna". Od 20 jest Int i Int ma seconds sposób wyszukuje kompilator niejawna konwersja, która pobiera Int i zwraca coś, ma metodę seconds, z poszukiwaniem ograniczonej zakresem swojej wywołania metody.

Zaimportowałeś DurationInt do swojego zakresu. Ponieważ DurationInt jest niejawną klasą z parametrem Int, jej konstruktor definiuje niejawną konwersję Int => DurationInt. DurationInt ma metodę seconds, więc spełnia wszystkie kryteria wyszukiwania. Dlatego kompilator zmienia twoje połączenie na new DurationInt(20).seconds **.

* Mam na myśli to luźno. 20.seconds() jest faktycznie nieprawidłowy, ponieważ metoda seconds nie ma listy parametrów, a zatem parens musi być pominięty w wywołaniu metody.

** W rzeczywistości nie jest to do końca prawdą, ponieważ DurationInt jest klasą wartości, więc kompilator uniknie zawijania liczby całkowitej, jeśli to możliwe.

+66

Każda wystarczająco zaawansowana technologia jest nieodróżnialna od magii. – ripper234

+4

Na szczęście większość IDE potrafi je rozróżnić! Niejawne konwersje są dość często wykorzystywane w Scali. Jeśli właśnie czytasz plik tekstowy, może to być mylące ("skąd ta metoda pochodzi"), ale przy odpowiednim wsparciu narzędzi powinieneś być w stanie znaleźć drogę, w którym punkt Scala może być pięknie znaczący i zwięzły. (np. 20. sekund jest dużo bardziej czytelny niż "nowy DurationInt (20) .seconds()", dopóki wiesz jak to robi) –

+1

Jeśli używasz implicite, zawsze zadawaj sobie pytanie, czy istnieje sposób osiągnąć to samo bez ich pomocy. http://twitter.github.com/effectivescala/#Types i Generics-Implicits – oluies

6

"Magia", która się tam dzieje, nazywa się "pośrednią konwersją". Importujesz niejawne konwersje, a niektóre z nich obsługują konwersję między Int (i Double) a Duration. Właśnie z tym masz do czynienia.