2009-06-17 35 views
22

在斯卡拉,为什么我可以省略T m 0(而不是T.m(0))中的点和制动器?我可以在Scala中忽略哪些字符?

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 
     ^

回答

36

前面的示例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 
} 

一个在这里它是在使用中:

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的标识符,虽然有限制后缀符号的通话,只能使用四个标识符作为前缀:〜,!, - 和+。现在,当你尝试“m 0”时,Scala放弃它作为一元操作符,理由是它不是有效的(〜,!, - 和+)。它发现“m”是一个有效的对象 - 它是一个函数,而不是一个方法,所有的函数都是对象。

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

+0

不要列出使用:::和::作为前缀符号吗? – andychase 2013-04-12 21:57:14

3

我相信操作符语法样式只有在左侧有明确的对象时才起作用。该语法旨在让您以自然的方式表达“操作数运算符”样式操作。

+1

我不明白你是什么意思的显式对象,但你可以有几乎任何东西评估左侧的对象,对不对? (...离开?) – 2009-08-05 23:01:11

相关问题