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
私はこのアプローチが好きです、それはより明確で、したがって読者にとってより明確です。
Lukasz Korzybski 2012年

4
どうやらそれが現在推奨されているスタイル(docs.scala-lang.org/style/declarations.html#procedure_syntax)なので、これを受け入れられる答えに変更します。
Esko Luontola 2014年

1
私もそれに同意します。=のない構文は言語から完全に削除する必要があると思います
Ahmed Soliman Farghal 2014

7
MartinOderskyは基調講演「ScalawithStyle」で、これは歴史的な間違いであると述べています。彼はこの構文を(=なしで)追加して、Java開発者が混乱しないように「Unit」を非表示にできるようにする必要がありました。また、彼はそれが将来削除されるだろうと述べました。
tabdulradi 2014

2
メソッド定義で等号を忘れた場合に警告する方法はありますか?たとえば、コンパイラオプションとして、または任意のソース分析ツールで?
VasiliNovikov 2014年

42

更新:Scala-2.10以降、等号を使用することをお勧めします。古い答え:

返さUnitれるメソッドは、常に等しくない構文を使用する必要があります。これにより、APIに引き継がれる実装の潜在的なミスを回避できます。たとえば、誤って次のようなことをした可能性があります。

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

もちろん些細な例ですが、これがどのように問題になるかがわかります。最後の式は返さないため、Unitメソッド自体はUnit。以外の戻り値の型になります。これはパブリックAPIで公開されており、今後他の問題が発生する可能性があります。等しくない構文では、最後の式が何であるかは関係ありません。Scalaは戻り値の型をとして修正しUnitます。

また、2文字のクリーナーです。:-)また、等しくない構文を使用すると、コードが少し読みやすくなると思う傾向があります。問題のメソッドがUnit有用な値ではなく、戻ることはより明白です。

関連する注記として、抽象メソッドに類似した構文があります。

trait Foo {
  def bar(s: String)
}

メソッドにbarは署名がありますString=>Unit。Scalaは、抽象メンバーの型アノテーションを省略するとこれを行います。繰り返しになりますが、これはよりクリーンで、(私は)読みやすくなっています。


3
等号使用していないことも、Scalaのスタイルガイドで推奨です:davetron5000.github.com/scala-style/types/inference/...
エスコLuontola

6
私はそのビットを書いたので、参照を比較検討するときはおそらくそれを覚えておく必要があります。:-)
Daniel Spiewak 2010年

笑、それで私は私のガールフレンドにこの小さな交換について説明しましたが、私の貧弱な発音のために「ビット」は「雌犬」として出てきました。言うまでもなく、喜劇が続いた。
Saem 2010年

10
ScalaDays 2013、Martin Odersky、基調講演-Scala with Style第45章:プロシージャ宣言(構文が等しくない)は避ける必要があります。
セニア2013

4
公式スタイルガイドはこれをもう推奨していません:docs.scala-lang.org/style/declarations.html#procedure_syntax
sbilstein

12

Unitを返す定義を除いて、等号を使用する必要あります。

この後者の場合、等号を無視することができます。ただし、この構文は非推奨になる可能性があるため、避けるのが最善です。等号を使用し、戻り値の型を宣言すると、常に機能します。


書籍、メーリングリスト、ソースコード。ちなみに、その時以来、後者の構文が非推奨になる可能性は低いことが明らかになり、多くの人に支持されています。
ダニエルC.ソブラル2013年

1
docs.scala-lang.org/style/types.html#function_valuesとにかく、タイプスタイルガイドが常に=を使用していることを示しているように見えます。
BeepDog 2014年

4

メソッドについては、Scalaスタイルガイドはプロシージャ構文ではなくequals構文を推奨しています

プロシージャの構文

手順の構文は、簡潔にするために混乱する傾向があるため、避けてください。

// don't do this
def printBar(bar: Baz) {
  println(bar)
}
// write this instead
def printBar(bar: Bar): Unit = {
  println(bar)
}

0

1つ:Unitを返す必要があるメソッドの最後のステートメントがUnitを返さないことを想像してください。等しくない構文を使用すると非常に便利です。いくつかのユースケースが見られるので、これが非推奨にならないことを願っています。


0

時間の経過とともにデフォルトのスタイルが変更され、これは回答へのコメントの多くで言及されているため、公式のスタイルガイドで=は関数宣言に構文を使用することをお勧めします。


1
あなたが提供したリンクは、プロシージャ(つまり、Unitを返す関数)ではなく、関数についてのみ説明しています。
Esko Luontola 2014年

そうです、@ EskoLuontola、申し訳ありませんが、開いていた多くのタブの1つから間違ったリンクをコピーした可能性があり、更新されています。
BeepDog 2014

0

戻り値を持たないメソッドの場合、そのようなメソッドを表現する方法は、中括弧で囲まれたブロックを使用したメソッドに従って、結果タイプと等号を除外することです。この形式では、メソッドはプロシージャのように見えます。これは、副作用のためにのみ実行されるメソッドです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.