Kiedy używać znaku równości w deklaracji metody Scala?

85

Ze znakiem równości:

object HelloWorld {
  def main(args: Array[String]) = {
    println("Hello!")
  }
}

Bez znaku równości:

object HelloWorld {
  def main(args: Array[String]) {
    println("Hello!")
  }
}

Oba powyższe programy działają w ten sam sposób. W poście na blogu Rzeczy, których nie lubię w Scali przeczytałem, że gdy brakuje znaku równości, metoda zwróci Unit(tak samo jak w Javie void), więc metody zwracające wartość muszą używać znaku równości. Ale metody, które nie zwracają wartości, można zapisać w dowolny sposób.

Jaka jest najlepsza praktyka dotycząca używania znaku równości w metodach Scala, które nie zwracają wartości?

Esko Luontola
źródło

Odpowiedzi:

108

Właściwie to całkiem mocno nie zgadzam się z Danielem. Myślę, że nie należy nigdy używać składni nierównej . Jeśli Twoja metoda jest ujawniana jako interfejs API i obawiasz się przypadkowego zwrócenia niewłaściwego typu, dodaj jawną adnotację typu:

object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello!")
    123
  }
}

Nierówna składnia jest krótsza i może wyglądać na „czystszą”, ale myślę, że po prostu dodaje możliwość pomyłki. Czasami zapomniałem dodać znak równości i uważałem, że moja metoda zwraca wartość, podczas gdy w rzeczywistości zwracała wartość Unit. Ponieważ składnie nierówne i równe z wnioskami typu są tak wizualnie podobne, łatwo jest przeoczyć ten problem.

Chociaż kosztuje mnie to trochę więcej pracy, wolę jawne adnotacje typu, gdy mają one znaczenie (a mianowicie odsłonięte interfejsy).

Jorge Ortiz
źródło
1
Podoba mi się to podejście, jest bardziej wyraźne, a przez to bardziej czytelne dla czytelnika.
Łukasz Korzybski
4
Najwyraźniej jest to teraz zalecany styl ( docs.scala-lang.org/style/declarations.html#procedure_syntax ), więc zmieniam to tak, aby była akceptowaną odpowiedzią.
Esko Luontola
1
Z tym też się zgadzam, myślę, że składnia bez
znaku
7
Martin Odersky w swoim przemówieniu „Scala with Style” powiedział, że był to historyczny błąd. Musiał dodać tę składnię (bez =), aby mógł ukryć „Unit” przed programistami Java, aby się nie pomylić. Wspomniał również, że zostanie on usunięty w przyszłości.
tabdulradi,
2
Czy istnieje sposób na WARN, jeśli w definicji metody zapomniano o znaku równości? Na przykład jako opcja kompilatora lub w dowolnym narzędziu do analizy źródła?
VasiliNovikov
42

AKTUALIZACJA: od Scala-2.10 preferowane jest używanie znaku równości. Stara odpowiedź:

Metody, które zwracają, Unitpowinny zawsze używać składni różnej od równości. Pozwala to uniknąć potencjalnych błędów w implementacji przenoszonych do API. Na przykład mogłeś przypadkowo zrobić coś takiego:

object HelloWorld {
  def main(args: Array[String]) = {
    println("Hello!")
    123
  }
}

Oczywiście banalny przykład, ale widać, że może to być problem. Ponieważ ostatnie wyrażenie nie zwraca Unit, sama metoda będzie miała inny typ zwrotu niż Unit. Jest to ujawniane w publicznym interfejsie API i może powodować inne problemy w przyszłości. W przypadku składni różnej od równości nie ma znaczenia, jakie jest ostatnie wyrażenie, Scala ustala zwracany typ jako Unit.

Jest to również czystsze dwie postacie. :-) Wydaje mi się również, że składnia nierówności sprawia, że ​​kod jest trochę łatwiejszy do odczytania. Bardziej oczywiste jest, że dana metoda zwraca Unitraczej niż jakąś użyteczną wartość.

W związku z tym istnieje analogiczna składnia dla metod abstrakcyjnych:

trait Foo {
  def bar(s: String)
}

Metoda barma podpis String=>Unit. Scala robi to, gdy pominiesz adnotację typu na abstrakcyjnym elemencie członkowskim. Po raz kolejny jest to czystsze i (myślę) łatwiejsze do odczytania.

Daniel Śpiewak
źródło
3
Niestosowanie
Esko Luontola
6
Napisałem ten fragment, więc prawdopodobnie powinieneś o tym pamiętać podczas ważenia odniesienia. :-)
Daniel Śpiewak
LoL, więc opisałem tę małą wymianę zdań mojej dziewczynie, poza tym, że z powodu mojej słabej wymowy „bit” wyszedł jako „suka”. Nie trzeba dodawać, że nastąpiła komedia.
Saem
10
ScalaDays 2013, Martin Odersky, Keynote - Scala with Style rozdział 45 : deklaracja procedury (składnia różna od równości) powinna być unikana.
senia
4
Oficjalny przewodnik po stylach już tego nie zaleca: docs.scala-lang.org/style/declarations.html#procedure_syntax
sbilstein
12

W deklaracjach wywołań należy używać znaku równości, z wyjątkiem definicji zwracających Unit.

W tym ostatnim przypadku, mogą zrzec znak równymi. Ta składnia może być jednak przestarzała, więc najlepiej jej unikać. Używanie znaku równości i deklarowanie zwracanego typu zawsze będzie działać.

Daniel C. Sobral
źródło
Książki, lista mailingowa, kod źródłowy. Nawiasem mówiąc, od tego czasu stało się jasne, że jest mało prawdopodobne, aby ta ostatnia składnia została przestarzała i jest preferowana przez wielu.
Daniel C. Sobral
1
docs.scala-lang.org/style/types.html#function_values Wygląda na to, że przewodnik po stylach typów wskazuje, że i tak używa = cały czas.
BeepDog
4

W przypadku metod Scala Style Guide zaleca składnię equals w przeciwieństwie do składni procedury

Składnia procedury

Unikaj składni procedury, ponieważ jest ona myląca z powodu niewielkiego zysku w zwięzłości.

// don't do this
def printBar(bar: Baz) {
  println(bar)
}
// write this instead
def printBar(bar: Bar): Unit = {
  println(bar)
}
cmd
źródło
0

Jedna rzecz: wyobraź sobie ostatnią instrukcję metody, która powinna zwrócić Unit, nie zwraca Unit. Używanie nierównomiernej składni jest wtedy bardzo wygodne, mam nadzieję, że nie będzie to przestarzałe, ponieważ widzę kilka przypadków użycia tego

jos
źródło
0

W miarę upływu czasu styl domyślny uległ zmianie, o czym wspomniano w wielu komentarzach do odpowiedzi, dlatego w oficjalnym przewodniku po stylach zaleca się używanie =składni do deklaracji funkcji.

BeepDog
źródło
1
Link, który podałeś, mówi tylko o funkcjach, a nie procedurach (tj. Funkcjach, które zwracają Unit).
Esko Luontola
Masz rację, @EskoLuontola, przepraszam za to, prawdopodobnie skopiowałem zły link z jednej z wielu otwartych kart, został zaktualizowany.
BeepDog,
0

w przypadku metody, która nie ma wartości zwracanej, sposobem wyrażenia takich metod jest pominięcie typu wyniku i znaku równości, po metodzie z blokiem zamkniętym w nawiasach klamrowych. W tej formie metoda wygląda jak procedura, metoda, która jest wykonywana tylko z powodu efektów ubocznych.

sofiene zaghdoudi
źródło