TheBigBlue 2009-07-21
数学运算
你可以通过中缀操作符,加号(+),减号(-),乘号(*),除号(/)和余数(%),在任何数类型上调用数学方法。以下是一些例子:
51CTO编辑推荐:Scala编程语言专题
scala> 1.2 + 2.3 res6: Double = 3.5 scala> 3 - 1 res7: Int = 2 scala> 'b' - 'a' res8: Int = 1 scala> 2L * 3L res9: Long = 6 scala> 11 / 4 res10: Int = 2 scala> 11 % 4 res11: Int = 3 scala> 11.0f / 4.0f res12: Float = 2.75 scala> 11.0 % 4.0 res13: Double = 3.0当左右两个操作数都是整数类型时(Int,Long,Byte,Short,或Char),/操作符将返回给你商的整数部分,去掉余数部分。%操作符指明它的余数。
用%符号得到的浮点数余数部分并不遵循IEEE754标准的定义。IEEE754在计算余数时使用四舍五入除法,而不是截尾除法,因此余数的计算与整数的余数操作会有很大的不同。如果你的确想要IEEE754的余数,可以调用scala.Math里的IEEEremainder,例如:
scala> Math.IEEEremainder(11.0, 4.0) res14: Double = -1.0数类型还提供了一元前缀+和-操作符(方法unary_+和unary_-),允许你指示文本数是正的还是负的,如-3或+4.0。如果你没有指定一元的+或-,文本数被解释为正的。一元符号+也存在只是为了与一元符号-相协调,不过没有任何效果。一元符号-还可以用来使变量变成负值。举例如下:
scala> val neg = 1 + -3 neg: Int = -2 scala> val y = +3 y: Int = 3 scala> -neg res15: Int = 2关系和逻辑操作
你可以用关系方法:大于(>),小于(< ),大于等于(>=)和小于等于(< =)比较数类型,像等号操作符那样,产生一个Boolean结果。另外,你可以使用一元操作符!(unary_!方法)改变Boolean值。以下是一些例子:
scala> 1 > 2 res16: Boolean = false scala> 1 < 2 res17: Boolean = true scala> 1.0 < = 1.0 res18: Boolean = true scala> 3.5f >= 3.6f res19: Boolean = false scala> 'a' >= 'A' res20: Boolean = true scala> val thisIsBoring = !true thisIsBoring: Boolean = false scala> !thisIsBoring res21: Boolean = true逻辑方法,逻辑与(&&)和逻辑或(||),以中缀方式带Boolean操作数并产生Boolean结果。如:
scala> val toBe = true toBe: Boolean = true scala> val question = toBe || !toBe question: Boolean = true scala> val paradox = toBe && !toBe paradox: Boolean = false与Java里一样,逻辑与和逻辑或有短路:short-circuit的概念:用这些操作符建造的表达式仅评估最少能决定结果的部分。换句话说,逻辑与和逻辑或表达式的右手侧部分在左手侧部分能决定结果时就不再被评估了。举个例子,如果逻辑与表达式的左手侧计算结果为false,那么表达式的结果将注定是false,因此右手侧部分不再做评估。与之类似,如果逻辑或表达式的左手侧部分计算结果为true,那么表达式的结果将必然是true,于是右手侧部分不再被计算。下面是一些例子:
scala> def salt() = { println("salt"); false } salt: ()Boolean scala> def pepper() = { println("pepper"); true } pepper: ()Boolean scala> pepper() && salt() pepper salt res22: Boolean = false scala> salt() && pepper() salt res23: Boolean = false第一个表达式中,pepper和salt都被调用,但第二个里,只有salt被调用。因为salt返回false,所以就没必要调用pepper了。
注意
或许你会想知道如果操作符都只是方法的话短路机制是怎么工作的呢。通常,进入方法之前所有的参数都会被评估,因此方法怎么可能选择不评估他的第二个参数呢?答案是因为所有的Scala方法都有延迟其参数评估乃至取消评估的设置。
位操作符
Scala让你能够使用若干位方法对整数类型的单个位执行操作。有:按位与运算(&),按位或运算(|)和按位异或运算(^)。按位异或方法对它的操作数执行互斥或:exclusive or操作。一致的位产生0。差异的位产生1。因此0011 ^ 0101产生0110。一元按位取补操作符(~,方法unary_~),反转它的操作数的每一位。例如:
scala> 1 & 2 res24: Int = 0 scala> 1 | 2 res25: Int = 3 scala> 1 ˆ 3 res26: Int = 2 scala> ~1 res27: Int = -2第一个表达式,1 & 2,与运算了1(0001)和2(0010)的每一个位,并产生了0(0000)。第二个表达式,1 | 2,对同样的操作数的每一个位执行或运算,并产生3(0011)。第三个表达式,1 ^ 3,异或1(0001)和3(0011)的每一个位,产生2(0010)。最后的表达式,~1,转换了1(0001)的每一个位,产生了-2,二进制看起来是1111 1111 1111 1111 1111 1111 1111 1111 1111 1110。
Scala整数类型还提供了三个位移方法:左移(< < ),右移(>>)和无符号右移(>>>)。使用在中缀操作符方式时,位移方法会按照右侧指定的整数值次数逐位移动左侧的整数。左移和无符号右移在移动的时候填入零。右移则在移动时填入左侧整数的最高位(符号位)。举例如下:
scala> -1 >> 31 res38: Int = -1 scala> -1 >>> 31 res39: Int = 1 scala> 1 < < 2 res40: Int = 4