21

私は Scala プログラミング言語にまったく慣れていないので、こちらの講義ノートを読んでいるときに心に引っかかっていることを試していました。

コンス演算子がどのように機能するかを本当に理解できなかったと思います。ここに私が試したいくつかのことがあります:

擬似乱数ジェネレーターを作成してから、1 つのランダム値のリストを作成しようとしました。

scala> val gen = new java.util.Random
gen: java.util.Random = java.util.Random@1b27332

scala> gen nextInt 3 :: Nil
<console>:7: error: type mismatch;
 found   : List[Int]
 required: Int
       gen nextInt 3 :: Nil
                     ^

しかし、List(3) を nextnt メソッドに渡そうとしました。パラテーゼを使用したときは問題ありませんでした

scala> (gen nextInt 3) :: Nil
res69: List[Int] = List(1)

実行順序が気になったので調べる関数を作ってみた

scala> def pr(i:Int):Int = { println(i); i }
pr: (i: Int)Int

scala> pr(1) :: pr(2) :: pr(3) :: Nil
1
2
3
res71: List[Int] = List(1, 2, 3)

出力に見られるように、実行順序は出現順序と同じです。次に、「nextInt」関数に関するものかもしれないと思ったので、次のことを試しました。

scala> 1 + 2 :: Nil
res72: List[Int] = List(3)

最初に加算を実行し、その後に cons を実行します。ここに質問があります: と の違いは何gen nextInt 3 :: Nilですか1 + 2 :: Nil?

4

2 に答える 2

44

ここで重要な点が 2 つあります。優先順位固定性です。sepp2k が述べたように、スタック オーバーフローに関するこの質問は優先順位を説明していますが、引用されているルールは十分に完全ではなく、Scala 2.7 から Scala 2.8 への非常に小さな変更がありました。ただし、違いは主に で終わる演算子に関する=ものです。

fixityに関しては、Scala のほとんどすべてが左から右に読み取られます。これは、プログラマーが慣れているものです。ただし、Scala では、で終わる演算子:は右から左に読み取られます。

それでは、次の例を見てみましょう。

1 + 2 :: Nil

まず優先順位。最も優先順位の高いもの、+または:? 表によると、+が よりも優先される:ため、加算が最初に行われます。したがって、式は次のようになります。

((1).+(2)) :: Nil

現在、優先順位の競合はありませんが、 で::終わるため:、異なる固定性があります。右から左に読み取られるため、次のようになります。

Nil.::((1).+(2))

一方、これでは:

gen nextInt 3 :: Nil

すべての文字よりも優先されるため、演算子::は よりも優先されます。したがって、その固定性を思い出すと、次のようになります。nextInt:

gen nextInt Nil.::(3)

次になる

gen.nextInt(Nil.::(3))

その時点で、エラーは明らかです。

PS:この記事の執筆時点では、 は double の数値として解釈され、double 1.0 を 2 に追加する中置式を作成するため、(1).+(2)代わりに書いています。この構文は Scala 2.10.0 で非推奨になり、おそらくScala 2.11 に存在します。1.+(2)1.1.+(2)

于 2010-07-05T20:58:53.230 に答える
3

実行順序ではなく優先順位です。+よりも優先順位が高い::ため、a + b :: cとして解析され(a + b) :: cます。ただし、通常の名前を持つ infix メソッド呼び出しは優先順位が低いため、a foo b cとして解析されa foo (b c)ます。

scala での優先順位順に並べられた演算子のリストについては、この質問を参照してください。

于 2010-07-05T19:37:01.290 に答える