Scala では、次の例のT m 0
ように ( ) ではなく( )のドットと括弧を省略できるのはなぜですか?T.m(0)
scala> object T { def m(i:Int) = 0 == i }
defined module T
scala> T m 0
res19: Boolean = true
n(0)
しかし、なぜ次の括弧を省略できないのでしょうか?
scala> def n(i:Int) = 0 == i
n: (Int)Boolean
scala> n 0
<console>:1: error: ';' expected but integer literal found.
n 0
^
ベストアンサー1
前の例 T m 0 は、「演算子表記」の例です。Scala には、プレフィックス (単項と呼ばれる)、インフィックス、ポストフィックスの 3 種類の演算子表記があります。ここで、3 つの例を実際に見てみましょう。
class MyByte(val n : Int) {
require(n >= 0 && n <= 255)
def unary_! = new MyByte(n ^ 0xff)
def +(m : MyByte) = new MyByte(n + m.n)
def bits = (math.log(n) / math.log(2) + 1).toInt
override def toString = "0" * (8 - bits) + n.toBinaryString
}
ここで使用例を示します。
scala> val a = new MyByte(5)
a: MyByte = 00000101
scala> val b = new MyByte(10)
b: MyByte = 00001010
scala> ! a // Prefix/Unary
res58: MyByte = 11111010
scala> a + b // Infix
res59: MyByte = 00001111
scala> b bits // Postfix
res60: Int = 4
中置記法と後置記法では有効な Scala 識別子が受け入れられますが、後置記法を制限するという話もあり、プレフィックスとして使用できる識別子は ~、!、-、+ の 4 つだけです。
ここで、「m 0」を試みると、Scala は有効な単項演算子 (~、!、-、+) ではないという理由でこれを破棄します。Scala は、「m」が有効なオブジェクトであると判断します。つまり、これは関数であり、メソッドではありません。すべての関数はオブジェクトです。
「0」は有効な Scala 識別子ではないため、中置演算子にも後置演算子にもなりません。したがって、Scala は「;」を期待していると文句を言います。これは、2 つの (ほぼ) 有効な式、「m」と「0」を分離します。これを挿入すると、m には引数が必要であるか、それができない場合は、部分的に適用された関数にするために「_」が必要であると文句を言います。