我可以在Scala中省略哪些字符?

tha*_*att 23 syntax scala

在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
Run Code Online (Sandbox Code Playgroud)

但为什么我不能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
         ^
Run Code Online (Sandbox Code Playgroud)

Dan*_*ral 37

前一个例子T m 0是"操作符号"的一个例子.Scala有三种类型的运算符表示法,前缀(称为一元),中缀和后缀.让我们看一下这三个实例的例子:

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
}
Run Code Online (Sandbox Code Playgroud)

它在这里使用:

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
Run Code Online (Sandbox Code Playgroud)

虽然中缀和后缀符号接受任何有效的Scala标识符,但是有关于限制后缀表示法的说法,只有四个标识符可以用作前缀:〜,!, - 和+.

现在,当你尝试"m 0"时,Scala将其作为一元算子丢弃,理由是它不是有效的(〜,!, - 和+).它发现"m"是一个有效的对象 - 它是一个函数,而不是一个方法,所有函数都是对象.

由于"0"不是有效的Scala标识符,因此它既不能是中缀也不能是后缀运算符.因此,Scala抱怨它预期";" - 它将两个(几乎)有效的表达式分开:"m"和"0".如果你插入它,那么它会抱怨m需要一个参数,或者,如果失败了,"_"将它变成一个部分应用的函数.

  • @ asperous.us No.以`:`结尾的运算符有不同的[fixity](http://en.wikipedia.org/wiki/Operator_associativity):它们是_right associative_而不是_left associative_,但它们都是中缀运算符相同. (2认同)