Когда использовать знак равенства в объявлении метода Scala?

85

Со знаком равенства:

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

Без знака равенства:

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

Обе вышеуказанные программы выполняются одинаково. В сообщении блога « Вещи, которые мне не нравятся в Scala» я прочитал, что, когда отсутствует знак равенства, метод будет возвращать Unit(как и в Java void), поэтому методы, возвращающие значение, должны использовать знак равенства. Но методы, которые не возвращают значение, можно записать в любом случае.

Как лучше всего использовать знак равенства в методах Scala, которые не возвращают значение?

Эско Луонтола
источник

Ответы:

108

На самом деле я категорически не согласен с Дэниелом. Я думаю , что неравной синтаксис не должен никогда использоваться. Если ваш метод представлен как API, и вы беспокоитесь о том, что случайно не вернет неправильный тип, добавьте явную аннотацию типа:

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

Неравный синтаксис короче и может выглядеть «чище», но я думаю, что это только добавляет возможности путаницы. Иногда я забывал добавить знак равенства и полагал, что мой метод возвращает значение, хотя на самом деле он возвращал Unit. Поскольку синтаксисы неравенства и равенства с предполагаемым типом визуально очень похожи, эту проблему легко упустить.

Хотя это требует от меня немного больше работы, я предпочитаю явные аннотации типов, когда они имеют значение (а именно, открытые интерфейсы).

Хорхе Ортис
источник
1
Мне нравится этот подход, он более явный и, следовательно, более понятный для читателя.
Лукаш Коржибски
4
По-видимому, теперь это рекомендуемый стиль ( docs.scala-lang.org/style/declarations.html#procedure_syntax ), поэтому я меняю его на принятый ответ.
Эско Луонтола
1
Я тоже согласен с этим, я думаю, что синтаксис без = следует вообще удалить из языка
Ахмед Солиман Фергал
7
Мартин Одерский в своем выступлении «Скала со стилем» сказал, что это историческая ошибка. Ему пришлось добавить этот синтаксис (без =), чтобы он мог скрыть «Unit» от разработчиков Java, чтобы они не запутались. Также он отметил, что в будущем он будет удален.
tabdulradi 05
2
Есть ли способ ПРЕДУПРЕЖДЕНИЕ, если в определении метода был забыт знак равенства? Как вариант компилятора, например, или в любом инструменте анализа исходного кода?
VasiliNovikov
42

ОБНОВЛЕНИЕ: начиная с Scala-2.10 предпочтительнее использовать знак равенства. Старый ответ:

Методы, которые возвращают, всегдаUnit должны использовать синтаксис не равенства. Это позволяет избежать возможных ошибок при переносе реализации в API. Например, вы могли случайно сделать что-то вроде этого:

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

Конечно, тривиальный пример, но вы понимаете, в чем проблема. Поскольку последнее выражение не возвращается Unit, сам метод будет иметь тип возврата, отличный от Unit. Это доступно в общедоступном API и может вызвать другие проблемы в будущем. С синтаксисом non-equals, неважно, какое последнее выражение, Scala исправляет возвращаемый тип как Unit.

Это также очиститель двух персонажей. :-) Я также склонен думать, что синтаксис не равенства делает код немного легче читаемым. Более очевидно, что рассматриваемый метод возвращает, Unitа не какое-то полезное значение.

Кстати, есть аналогичный синтаксис для абстрактных методов:

trait Foo {
  def bar(s: String)
}

У метода barесть подпись String=>Unit. Scala делает это, когда вы опускаете аннотацию типа для абстрактного члена. Еще раз, это чище и (я думаю) легче читать.

Даниэль Спивак
источник
3
Не использовать знак равенства также рекомендуется в Руководстве по стилю Scala: davetron5000.github.com/scala-style/types/inference/…
Эско Луонтола
6
Я написал этот фрагмент, так что вам, вероятно, следует помнить об этом при взвешивании эталона. :-)
Daniel Spiewak
LoL, поэтому я описал этот небольшой обмен своей девушке, за исключением того, что из-за моего плохого произношения слово «немного» получилось «сука». Разумеется, последовала комедия.
Saem
10
ScalaDays 2013, Мартин Одерский, Keynote - Scala со стилем, глава 45 : следует избегать объявления процедуры (синтаксис, не равный).
сеня 06
4
Официальное руководство по стилю больше этого не рекомендует: docs.scala-lang.org/style/declarations.html#procedure_syntax
sbilstein
12

Вы должны использовать знак равенства в объявлениях вызовов, за исключением определений, возвращающих Unit.

В последнем случае вы можете отказаться от знака равенства. Однако этот синтаксис может быть устаревшим, поэтому его лучше избегать. Использование знака равенства и объявление типа возврата всегда будет работать.

Дэниел С. Собрал
источник
Книги, список рассылки, исходный код. Кстати, с тех пор стало ясно, что последний синтаксис вряд ли будет устаревшим, и многие его предпочитают.
Daniel C. Sobral
1
docs.scala-lang.org/style/types.html#function_values Похоже, руководство по стилю типов в любом случае указывает использование = постоянно.
BeepDog
4

Для методов Scala Style Guide рекомендует использовать синтаксис равенства вместо синтаксиса процедуры.

Синтаксис процедуры

Избегайте синтаксиса процедуры, так как он сбивает с толку и дает очень мало преимуществ для краткости.

// don't do this
def printBar(bar: Baz) {
  println(bar)
}
// write this instead
def printBar(bar: Bar): Unit = {
  println(bar)
}
cmd
источник
0

Одно: представьте, что последний оператор метода, который должен возвращать Unit, не возвращает Unit. Тогда использование неравного синтаксиса очень удобно, я надеюсь, что это не будет устаревшим, поскольку я вижу несколько вариантов его использования.

Джос
источник
0

С течением времени стиль по умолчанию менялся, и это упоминалось во многих комментариях к ответам, в официальном руководстве по стилю рекомендуется использовать =синтаксис для объявлений функций.

BeepDog
источник
1
Ссылка, которую вы предоставили, говорит только о функциях, а не о процедурах (т.е. функциях, возвращающих Unit).
Эско Луонтола
Вы правы, @EskoLuontola, извините за это, я, вероятно, скопировал неправильную ссылку из одной из многих вкладок, которые я открыл, она обновлена.
BeepDog
0

для метода, который не имеет возвращаемого значения, способ выражения таких методов заключается в том, чтобы не указывать тип результата и знак равенства, следуя за методом блоком, заключенным в фигурные скобки. В этой форме метод выглядит как процедура, метод, который выполняется только из-за своих побочных эффектов.

Софиене Загдуди
источник