[解決済み】Scalaにおける中括弧と括弧の正式な違い、また、どのような場合に使用すべきなのか?
質問
関数に渡す引数を括弧で囲むのとでは、形式的にどのような違いがあるのでしょうか。
()
と中括弧で囲まれた
{}
?
から受けた感触は Scalaでプログラミング の本には、Scalaはかなり柔軟性があるから、一番好きなものを使えばいいということが書いてあるのですが、コンパイルできる場合とできない場合があるんです。
例えば、(あくまで例としてですが、この特定の例だけでなく、一般的なケースについて議論している回答があればありがたいです)。
val tupleList = List[(String, String)]()
val filtered = tupleList.takeWhile( case (s1, s2) => s1 == s2 )
=> error: simple expression の開始が不正です。
val filtered = tupleList.takeWhile{ case (s1, s2) => s1 == s2 }
=>で結構です。
解決方法は?
一度書こうとしたのですが、ルールがやや拡散しているため、結局あきらめました。基本的には、コツをつかむしかないでしょう。
中括弧と括弧を使い分けられるのは、メソッド呼び出しにパラメータを渡すときだけです。あなたは かもしれません メソッドが単一のパラメータを想定している場合のみ、括弧を中括弧に置き換えることができます。たとえば
List(1, 2, 3).reduceLeft{_ + _} // valid, single Function2[Int,Int] parameter
List{1, 2, 3}.reduceLeft(_ + _) // invalid, A* vararg parameter
しかし、これらのルールをよりよく理解するためには、さらに知っておくべきことがあります。
パレンによるコンパイルチェックの強化
Sprayの作者は、コンパイル時のチェックを強化するために丸括弧を推奨しています。 これはSprayのようなDSLでは特に重要です。 丸括弧を使うということは、コンパイラに一行で済ませるように指示することです。したがって、誤って二行以上与えてしまうと、コンパイラは文句を言うことになります。 中括弧の場合はそうではありません。例えば、どこかに演算子を忘れてしまった場合、コードはコンパイルされてしまい、予期しない結果や、見つけるのが非常に難しいバグが発生する可能性があります。 以下は意図的なものですが(式は純粋なので、少なくとも警告は出るでしょう)、ポイントを押さえています。
method {
1 +
2
3
}
method(
1 +
2
3
)
最初のものはコンパイルされ、2番目のものは
error: ')' expected but integer literal found
. 作者が書きたかったのは
1 + 2 + 3
.
デフォルトの引数を持つ複数パラメータのメソッドについても同様で、ペレンを使っているときに誤ってパラメータを区切るためのカンマを忘れることはあり得ません。
冗長性
冗長性に関して、見落としがちな重要な注意点があります。中括弧を使用すると、必然的に冗長なコードになります。 Scalaスタイルガイド には、中括弧は必ず一行で閉じるようにと明記されています。
... 閉鎖波括弧は最終行の直後の独立した行にあります。 関数の行になります。
IntelliJのような多くの自動再フォーマッターは、この再フォーマットを自動的に行ってくれます。 ですから、できる限り丸括弧を使うようにしましょう。
Infix記法
のように、infix記法を使用する場合
List(1,2,3) indexOf (2)
と書くと、パラメータが1つだけなら括弧を省略して
List(1, 2, 3) indexOf 2
. これはドットノテーションの場合ではありません。
また,1つのパラメータがマルチトークン式である場合,例えば
x + 2
または
a => a % 2 == 0
のように、式の境界を示すために括弧を使用しなければならない。
タプル
括弧を省略できる場合もあるので、次のようにタプルに追加の括弧が必要な場合もあります。
((1, 2))
のように、外側の括弧を省略できる場合もあります。
(1, 2)
. このため、混乱が生じることがあります。
関数/部分関数リテラルで
case
Scalaには、関数と部分関数リテラルのための構文があります。それは次のようなものです。
{
case pattern if guard => statements
case pattern => statements
}
その他の場所で使用できるのは
case
文は
match
と
catch
のキーワードを使用します。
object match {
case pattern if guard => statements
case pattern => statements
}
try {
block
} catch {
case pattern if guard => statements
case pattern => statements
} finally {
block
}
を使用することはできません。
case
ステートメントを他のコンテキストで使用します。
. ですから、もしあなたが
case
を選択した場合、あなたは
必要
という中括弧があります。関数と部分関数リテラルを区別するのは何かというと、答えは「文脈」です。Scalaが関数を期待すれば、関数が得られます。Scala が部分関数を期待すれば、部分関数が得られます。両方が期待されている場合は、曖昧さに関するエラーが発生します。
式とブロック
括弧は、部分式を作るために使用します。中括弧は、コードのブロックを作るのに使います(これは ではない 関数リテラルのような使い方をしないように注意してください。) コードのブロックは複数の文で構成され、それぞれの文はimport文、宣言、または式になります。このようになります。
{
import stuff._
statement ; // ; optional at the end of the line
statement ; statement // not optional here
var x = 0 // declaration
while (x < 10) { x += 1 } // stuff
(x % 5) + 1 // expression
}
( expression )
そのため、宣言や複数のステートメントが必要な場合は
import
などのように、中括弧が必要です。そして、式は文ですから、中括弧の中に括弧が現れることもあります。しかし、面白いことに、コードのブロックは
また
式は、どこでも使用することができます。
内部
という式があります。
( { var x = 0; while (x < 10) { x += 1}; x } % 5) + 1
つまり、式は文であり、コードのブロックは式であるから、以下はすべて有効である。
1 // literal
(1) // expression
{1} // block of code
({1}) // expression with a block of code
{(1)} // block of code with an expression
({(1)}) // you get the drift...
互換性がない場合
基本的に
{}
で
()
またはその逆を、他の場所で行うことができます。例えば
while (x < 10) { x += 1 }
これはメソッド呼び出しではないので、他の書き方ではダメです。まあ、中括弧を付けて
内部
を表す括弧は
condition
を使用するだけでなく、括弧を使用して
内側
で囲まれています。
while ({x < 10}) { (x += 1) }
では、お役に立てれば幸いです。
関連
-
[解決済み] Scalaの「コンテキストバウンド」とは何ですか?
-
[解決済み] A の値をキーとして Seq[A] を Map[Int, A] に変換する方法は?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] PHPの文字列で、シングルクオートとダブルクオートの違いは何ですか?
-
[解決済み] .の違いは何ですか?(ドット)と$(ドルマーク)の違いは何ですか?
-
[解決済み] Bashのシングルクォートとダブルクォートの違い
-
[解決済み] Scalaのオブジェクトとクラスの違い
-
[解決済み] 割り算で使う場合の「/」と「//」の違いは何ですか?
-
[解決済み] Scalaのcase classとclassの違いは何ですか?
-
[解決済み】Scalaのvarとvalの定義の違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Spark - アプリの投稿時に「設定にマスターURLが設定されている必要があります」というエラーが発生する
-
[解決済み] SparkはYarnクラスタ上で動作しています exitCode=13:
-
[解決済み] 実行時に変数の型を取得したい
-
[解決済み] NotUsedとDoneの理解
-
[解決済み] 理解する `andThen`
-
[解決済み] ScalaのDSLって何?[クローズド]
-
[解決済み] scalaのforeachループ
-
[解決済み] self-typesとtrait subclassの違いは何ですか?
-
[解決済み】Scalaで変数をキャストする方法は?
-
[解決済み] Scalaの==と.equalsの違いは何ですか?