Jakie są dokładne zasady, kiedy można pominąć (pomijać) nawiasy, kropki, nawiasy klamrowe, = (funkcje) itp.?
Na przykład,
(service.findAllPresentations.get.first.votes.size) must be equalTo(2).
service
jest moim przedmiotemdef findAllPresentations: Option[List[Presentation]]
votes
zwrotyList[Vote]
- muszą i być są funkcjami specyfikacji
Dlaczego nie mogę iść:
(service findAllPresentations get first votes size) must be equalTo(2)
?
Błąd kompilatora to:
„RestServicesSpecTest.this.service.findAllPresentations typu Option [List [com.sharca.Presentation]] nie przyjmuje parametrów”
Dlaczego myśli, że próbuję przekazać parametr? Dlaczego muszę używać kropek dla każdego wywołania metody?
Dlaczego musi (service.findAllPresentations get first votes size)
być equalTo (2) skutkuje:
„nie znaleziono: najpierw wartość”
Jednak „must be equalTo 2”
(service.findAllPresentations.get.first.votes.size)
musi być równe 2, czyli łączenie metod działa dobrze? - parametr łańcucha łańcucha obiektów.
Przejrzałem książkę i stronę internetową Scala i nie mogę znaleźć wyczerpującego wyjaśnienia.
Czy tak jest w rzeczywistości, jak wyjaśnia Rob H w pytaniu Stack Overflow Które znaki mogę pominąć w Scali? , że jedyny prawidłowy przypadek użycia dla pominięcia „.” jest przeznaczony do operacji w stylu „operand operator operand”, a nie do łączenia metod?
Definicje klas:
val
lubvar
może zostać pominięty w parametrach klasy, co spowoduje, że parametr stanie się prywatny.Dodanie var lub val spowoduje, że stanie się on publiczny (to znaczy, że zostaną wygenerowane metody dostępu i mutatory).
{}
można pominąć, jeśli klasa nie ma treści, to znaczyInstancja klasy:
Parametry ogólne można pominąć, jeśli mogą być wywnioskowane przez kompilator. Należy jednak pamiętać, że jeśli typy nie są zgodne, parametr typu jest zawsze pobierany, aby był zgodny. Tak więc bez określenia typu możesz nie otrzymać tego, czego oczekujesz - to znaczy danego
To da ci błąd typu (znaleziono Int, oczekiwany ciąg)
Podczas gdy to działa dobrze:
Ponieważ parametr typu, T, jest wywnioskowany jako najmniej powszechny nadtyp z dwóch - Any.
Definicje funkcji:
=
można usunąć, jeśli funkcja zwraca Jednostka (nic).{}
ponieważ treść funkcji może zostać usunięta, jeśli funkcja jest pojedynczą instrukcją, ale tylko wtedy, gdy instrukcja zwraca wartość (potrzebujesz=
znaku), to znaczyale to nie działa:
Zwracany typ funkcji można pominąć, jeśli można go wywnioskować (metoda rekurencyjna musi mieć określony typ zwracania).
()
można porzucić, jeśli funkcja nie przyjmuje żadnych argumentów, to znaczyktóry umownie jest zarezerwowany dla metod, które nie mają skutków ubocznych - o tym później.
()
nie jest w rzeczywistości pomijana jako taka podczas definiowania paramentera pass by name , ale w rzeczywistości jest to całkiem inna semantycznie notacja, to znaczyMówi, że myOp przyjmuje parametr przekazywany przez nazwę, co skutkuje ciągiem znaków (to znaczy może być blokiem kodu, który zwraca ciąg), w przeciwieństwie do parametrów funkcji,
która mówi, że
myOp
przyjmuje funkcję, która ma zero parametrów i zwraca String.(Pamiętaj, parametry przekazywania przez nazwę są kompilowane w funkcje; to po prostu poprawia składnię).
()
można pominąć w definicji parametru funkcji, jeśli funkcja przyjmuje tylko jeden argument, na przykład:Ale jeśli wymaga więcej niż jednego argumentu, musisz dołączyć ():
Sprawozdania:
.
można zrezygnować z używania notacji operatorów, która może być używana tylko dla operatorów wrostków (operatorów metod pobierających argumenty). Zobacz odpowiedź Daniela, aby uzyskać więcej informacji..
może być również usunięty z listy funkcji postfiksowych()
można usunąć dla operatorów postfiksowych list.tail()
nie można używać z metodami zdefiniowanymi jako:Ponieważ ta notacja jest przez konwencję zarezerwowana dla metod, które nie mają skutków ubocznych, takich jak List # tail (czyli wywołanie funkcji bez skutków ubocznych oznacza, że funkcja nie ma żadnego obserwowalnego efektu, z wyjątkiem wartości zwracanej).
()
można porzucić dla notacji operatora podczas przekazywania pojedynczego argumentu()
może być wymagane użycie operatorów postfiksowych, które nie znajdują się na końcu instrukcji()
może być wymagane wyznaczenie zagnieżdżonych instrukcji, końców funkcji anonimowych lub operatorów, które przyjmują więcej niż jeden parametrPodczas wywoływania funkcji, która przyjmuje funkcję, nie można pominąć () w definicji funkcji wewnętrznej, na przykład:
Podczas wywoływania funkcji, która przyjmuje parametr typu „by-name”, nie można określić argumentu jako funkcji anonimowej bez parametrów. Na przykład, biorąc pod uwagę:
Musisz to nazwać:
lub
ale nie:
IMO, nadużywanie upuszczania typów zwracanych może być szkodliwe dla ponownego wykorzystania kodu. Wystarczy spojrzeć na specyfikację, aby znaleźć dobry przykład ograniczonej czytelności z powodu braku wyraźnych informacji w kodzie. Liczba poziomów pośrednich, aby faktycznie dowiedzieć się, jaki jest typ zmiennej, może być szalona. Miejmy nadzieję, że lepsze narzędzia mogą zapobiec temu problemowi i zachować zwięzły kod.
(OK, w celu skompilowania pełniejszej, zwięzłej odpowiedzi (jeśli coś przeoczyłem lub dostałem coś złego / niedokładnego, proszę o komentarz), dodałem na początku odpowiedzi. Pamiętaj, że to nie jest język specyfikacji, więc nie staram się, aby było dokładnie poprawne naukowo - po prostu bardziej jak karta referencyjna.)
źródło
Zbiór cytatów dających wgląd w różne warunki ...
Osobiście myślałem, że w specyfikacji będzie więcej. Jestem pewien, że musi być, po prostu nie szukam odpowiednich słów ...
Źródeł jest jednak kilka i zebrałem je razem, ale nic tak naprawdę kompletnego / kompleksowego / zrozumiałego / nie wyjaśnia mi powyższych problemów ...:
Z rozdziału 2, „Pisz mniej, rób więcej”, książki Programowanie Scala :
Z rozdziału 1, „Zero to Sixty: Introduction Scala”, książki Programming Scala :
Z wpisu na blogu Scala Syntax Primer :
Ze specyfikacji językowej:
Ze Scali dla uchodźców z języka Java, część 6: Jak pokonać Javę :
Jakie postacie mogę pominąć w Scali?
Ale to, co mnie również dezorientuje, to ten cytat:
Bo o ile widzę, nie jest przedmiotem, aby odebrać połączenie ...
źródło
Łatwiej jest mi przestrzegać tej praktycznej zasady: w wyrażeniach spacje zmieniają się między metodami i parametrami. W twoim przykładzie
(service.findAllPresentations.get.first.votes.size) must be equalTo(2)
analizuje jako(service.findAllPresentations.get.first.votes.size).must(be)(equalTo(2))
. Zwróć uwagę, że nawiasy wokół 2 mają większą zespolenie niż przestrzenie. Kropki mają również wyższą łączność, więc(service.findAllPresentations.get.first.votes.size) must be.equalTo(2)
przeanalizują jako(service.findAllPresentations.get.first.votes.size).must(be.equalTo(2))
.service findAllPresentations get first votes size must be equalTo 2
parses asservice.findAllPresentations(get).first(votes).size(must).be(equalTo).2
.źródło
Właściwie przy drugim czytaniu może to jest klucz:
Jak wspomniano w poście na blogu: http://www.codecommit.com/blog/scala/scala-for-java-refugees-part-6 .
Być może jest to w rzeczywistości bardzo ścisły „cukier składniowy”, który działa tylko wtedy , gdy skutecznie wywołujesz metodę, na obiekcie, który przyjmuje jeden parametr . na przykład
I nic więcej.
To wyjaśniałoby moje przykłady w pytaniu.
Ale jak powiedziałem, gdyby ktoś mógł wskazać, że znajduje się dokładnie tam, gdzie w specyfikacji języka jest to określone, byłoby to bardzo mile widziane.
Ok, jakiś miły gość (paulp_ z #scala) wskazał, gdzie w specyfikacji języka jest ta informacja:
Hmm - dla mnie to nie zazębia się z tym, co widzę lub po prostu tego nie rozumiem;)
źródło
Nie ma. Prawdopodobnie otrzymasz poradę dotyczącą tego, czy funkcja ma skutki uboczne. To jest fałszywe. Poprawka polega na tym, aby nie używać skutków ubocznych w rozsądnym zakresie dozwolonym przez firmę Scala. O ile nie jest to możliwe, wszystkie zakłady są wykluczone. Wszystkie zakłady. Stosowanie nawiasów jest elementem zbioru „wszystko” i jest zbędne. Nie zapewnia żadnej wartości, gdy wszystkie zakłady są wyłączone.
Ta rada jest zasadniczo próbą stworzenia systemu efektów który zawodzi (nie mylić z: jest mniej przydatny niż inne systemy efektów).
Staraj się nie mieć efektu ubocznego. Następnie zaakceptuj, że wszystkie zakłady są wyłączone. Ukrywanie się za de facto notacją składniową dla systemu efektów może i robi tylko krzywdę.
źródło