Scala运算符详解

转:http://houjp.com/2016/01/09/Scala%E8%BF%90%E7%AE%97%E7%AC%A6%E8%AF%A6%E8%A7%A3/

运算符的本质

在Scala中,真正的运算符只有直接赋值运算符(=),其他的的运算符其实都是方法(函数)。

val a = 1 + 2     // 等价于 1.+(2)
val b = 1 + 2 * 3 // 等价于 1.+(2.*(3))

运算符的重载

Scala中的运算符重载很简单,不需要多余的关键字,只要把运算符放在方法名的位置上就好了:

class MyClass(val x: Int) {
  def +(o: MyClass) = new MyClass(x + o.x)
  def *(o: MyClass) = new MyClass(x * o.x)

  override def toString: String = {
    x.toString
  }
}

object MyClass {

  def main(args: Array[String]) {
    val o1 = new MyClass(2)
    val o2 = new MyClass(3)

    println(o1 + o2)
    println(o1 * o2)
  }
}

重载运算符可以是任意长度,但是只能由符号或者字母中的一类构成($和_算作字母)。比如<:<是合法的,但是

前缀运算符

前缀运算符只支持四种:~!+-,分别用unary_作为前缀来定义:

class MyClass(val x: Int) {
  def unary_+ = new MyClass(x)
  def unary_- = new MyClass(-x)

  override def toString: String = {
    x.toString
  }
}

object MyClass {

  def main(args: Array[String]) {
    val o = new MyClass(2)

    println(+o)
    println(-o)
  }
}

后缀运算符

后缀运算符支持并非默认开启,如果使用时不注意很容易编译不通过或者产生语义问题,实际中也较少使用到,所以在此不做过多说明。

简单的来说后缀操作符也是用户自定义的一些以unary_为开头的方法,之后直接使用在操作数的后面即可,默认是同其左边的操作数相结合的

运算符的调用方向

前缀运算符调用方向从右至左,后缀运算符从左至右。对于中缀运算符,Scala做了一个规定:以:结尾的运算符为从右至左调用,其他的运算符从左至右调用。

对于+:,以下表达式是等价的:

a +: b +: c
a +: c.+:(b)
c.+:(b).+:(a)

也就是说,从右至左调用的运算符会将右边的对象作为调用方法的对象,同时同等优先级下最右侧的运算符先执行,反之亦然。

运算符的优先级

运算符的优先级是由第一个字符的优先级决定的,键盘上可以输入,且不是语法要素的符号的优先级见下表:

优先级运算符首字母备注
1~,@,#,?,\Java中不会出现的符号
2*,/,%乘除法
3+,-加减法
4:
5<,>移位运算符和比较运算符
6!,=等于和不等于
7&与运算符
8^异或运算符
9|或运算符
10$,_,英文字母$和_是可以写入标识符的符号,和上面的符号有本质区别

特别注意以下几点:

  1. 前缀运算符高于所有中缀运算符。
  2. 以=结尾而又不以=开始的运算符会被当做赋值运算符而优先级低于以上所有运算符。
  3. 第一个字符相同的运算符优先级相同,从左至右依次执行(以:结尾的从右向左依次执行)。

对于第三点请参照以下程序及运行结果进行理解:

// 程序
class MyClass(val x: Int) {
  def :*(o: MyClass) = new MyClass(x * o.x)
  def :+(o: MyClass) = new MyClass(x + o.x)

  override def toString: String = {
    x.toString
  }
}

object MyClass {

  def main(args: Array[String]) {
    val o1 = new MyClass(2)
    val o2 = new MyClass(3)
    val o3 = new MyClass(4)

    println(o1 :+ o2  :* o3)
    println(o1 :* o2  :+ o3)
  }
}

// 运行结果
20
10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值