59

Scalaでは、caseclassを作成し、次case class Foo(x:Int)のようにリストに入れることができます。

List(Foo(42))

さて、ここでは何も奇妙なことはありません。以下は私には奇妙です。演算子::はリスト上の関数ですよね?Scalaで引数が1つある関数なら、中置記法で呼び出すことができます。例は、オブジェクト1 + 2の関数です。定義したクラスには演算子がありませんが、次のことはどのように可能ですか?(+)IntFoo::

Foo(40) :: List(Foo(2))

Scala 2.8 RC1では、インタラクティブプロンプトから次の出力が得られます。

scala> case class Foo(x:Int)
defined class Foo

scala> Foo(40) :: List(Foo(2))
res2: List[Foo] = List(Foo(40), Foo(2))

続けて使えますが、説明は?

4

4 に答える 4

54

仕様から:

6.12.3 InfixOperations中置演算子は、任意の識別子にすることができます。中置演算子には、次のように定義された優先順位と結合性があります。

..。

演算子の結合性は、演算子の最後の文字によって決まります。コロン「:」で終わる演算子は右結合です。他のすべての演算子は左結合です。

コンパイラの「typer」フェーズを通過した後にプログラムを印刷することで、これらのルールがScalaでどのように適用されるかを常に確認できます。

scala -Xprint:typer -e "1 :: Nil"

val r: List[Int] = {
  <synthetic> val x$1: Int = 1;
  immutable.this.Nil.::[Int](x$1)
};
于 2010-05-13T14:10:59.553 に答える
24

で終わり:ます。これが、この関数が右側のListクラス(ここのクラス)で定義されていることを示しています。

だから、それはあなたの例List(Foo(2)).::(Foo(40))ではありません。Foo(40).::(List(Foo(2)))

于 2010-05-13T14:01:12.007 に答える
20

与えられた答えに欠けている1つの側面は::、パターンマッチング式をサポートすることです。

List(1,2) match {
  case x :: xs => println(x + " " + xs)
  case _ => println("")
}

クラス::が定義されています:

final case class ::[B](private var hd: B, private[scala] var tl: List[B]) 

したがってcase ::(x,xs)、同じ結果が得られます。case x :: xsデフォルトのエクストラクタ::がcaseクラスに定義されており、中置で使用できるため、この式は機能します。

于 2010-05-18T11:54:47.173 に答える
19

Foo今定義したクラスには::演算子がないので、次のことが可能です。

Foo(40) :: List(Foo(2))

メソッド名がコロン()で終わる場合、メソッドは右のオペランド:で呼び出されます。これはここに当てはまります。メソッド名がコロンで終わっていない場合、メソッドは左側のオペランドで呼び出されます。たとえば、はで呼び出されます。a + b+a

したがって、あなたの例で::は、はその右側のオペランドにあるメソッドであり、これはListです。

于 2010-05-13T14:26:52.043 に答える