Scala学习(六)——运算符

Scala学习(六)——运算符

本站内容版权属于本人。转载须告知本人,写明出处,并在文首提供指向本站对应文章的链接。
本文链接:Scala学习(六)——运算符
简介

在任何语言里,运算符都是很重要的部分,Scala也不例外。然而,从某种意义上讲,Scala根本就没有除了直接赋值运算符=以外的运算符。这是怎么回事儿呢?接下来就开始讲。

本质

在Scala中,除了=以外,运算符其实都是方法。中缀运算符是一个参数的方法,前缀运算符和后缀运算符是无参方法。在其他语言中我们熟悉的表达式到了Scala中可能实质上只是一系列方法调用。比如:

在Scala学习(三)中说明for循环的时候提到过一个例子:

其中0 to 10就是类似于运算符的一种方法调用,其实质上是0.to(10)。当然,这里还包含了一个隐式转换,以后再讲。
方法和运算符运算没有本质的界限,方法调用也可以用类似运算符的方式完成:

重载

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

重载运算符可以是任意长度,但是只能由符号或者字母中的一类构成($_算作字母)。比如<:<是合法的,但是<a<是不合法的。
前缀运算符只支持四种:~!+-,分别用unary_作为前缀来定义:

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

调用方向

前缀运算符调用方向从右至左,后缀运算符从左至右。中缀运算符理论上来说两者都可,但考虑到使用习惯和需求,Scala做了一个规定:以:结尾的运算符为从右至左调用,其他的运算符从左至右调用。
调用方向会有什么影响呢?对于从左至右调用的运算符来说,比如+,以下表达式是等价的:

然而,对于+:运算符,以下表达式是等价的:

也就是说,从右至左调用的运算符会将右边的对象作为调用方法的对象,反之亦然。

优先级

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

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

另外,前缀运算符高于所有中缀运算符。以=结尾而又不以=开始的运算符会被当做赋值运算符而优先级低于以上所有运算符。

总结

Scala的运算符本质上就是方法,这和其他语言的思路有很大的不同。使用运算符重载可以使程序更加简洁,但是却更加难懂。不过,只要使用得当,就可以很好地控制危害,尽量利用其优势。错的不是语言,是使用者。虽然语言提供了这种特性,但程序员不可滥用。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

*

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据