Scala学习——操作符

原文发表于:http://nerd-is.in/2013-08/scala-learning-operators/

本章介绍如何实现自定以操作符。操作符和隐式转换通常用来构建领域特定语言(DSL)。本章还会介绍apply、update和unapply等特殊方法。

标志符

原来标志符是支持Unicode的…虽然我真的见过用中文名作为变量名的代码,但是我一向以来学到的都是:标志符,可以包含字母数字下划线(偶尔也能用$之类的),不能以数字开头。如果能用Unicode字符作为标志符,那么真是各种奇葩标志符都有可能出现了吧。我还是用着最传统的就好。

Scala中,标志符的选择比Java更多。详细的,我觉得不了解也是件好事,反正真正适合用来写代码的,就是键盘上那么几个键。了解一下,心里有个底,以后看见什么奇葩人物写了奇葩名字别太过惊讶就好。

Scala中,可以使用反引号`(一般在1左边那个)包含一些不能作为标志符的字符串,来使用它们。比如说关键字什么的。这只是类似于保命手段,请尽量避免使用。

中置、一元、赋值操作符

这三个放一起好了,应该也没太多要说的。

前面提过,如果一个方法有一个隐式的参数和一个显式的参数,那么这个方法调用的.和( )都可以省略。省略之后,就像是中置操作符了。什么叫中置操作符这种问题,就自己做功课去吧。所以,中置操作符就是个方法,定义操作符也就是定义个方法这么简单。

一元操作符只有一个参数。如果出现在参数之后,就是后置(postfix)操作符;出现在参数之前,就是前置(prefix)了。四个操作符,+ – ! ~,可以作为前置操作符,它们将会被转换城名为 unary_<prefix>的方法,是四个操作符之一。如 -a 相当于 a.unary_-

赋值操作符,就是常见的 +=-=这种感觉了。

赋值操作符有些点需要注意:

  • <=、>=、!=不是赋值操作符;
  • 以=号开头的操作符不是赋值操作符;

优先级

在学习C和Java的时候,这个话题应该是很早就提出来的。但Scala中却放到了这么后面。理由呢?因为Scala可以自己随意定义操作符,所以首先需要了解其他的东西,等能够自己定义操作符了,再来学习优先级问题。

除了赋值操作符之外,优先级由操作符的首字符决定。

最高优先级:除以下字符外的操作符字符
* / %
+ –
:
< >
! =
&
^
|
非操作符
最低优先级:赋值操作符

需要注意的再强调一下,优先级是由操作符的首字符决定的;赋值操作符的优先级是最低的。后置操作符的优先级低于中置操作符。

优先级这个东西,随着使用经验的增长,加上括号的使用,不会成为大问题才是。

结合性

结合性决定了当有一系列同一优先级的操作符时,它们的求值顺序。在Scala中,绝大部分的操作符都是左结合(从左到右)的,除了:1. 以冒号:结尾的操作符;2. 赋值操作符。而且,在右结合时,二元操作符的参数顺序也发生了变化:二元操作符是其第二个参数的方法。

apply和update方法

如果f不是方法或者是函数:

apply方法经常被用在伴生对象中用来构造对象,可以省去使用new来创建对象。而update方法经常被使用在于数据和映射之类的集合有关的地方。

提取器(L2)

提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。

每一个样例类都自动具备apply和unapply方法,样例类在14章介绍。

带单个参数或无参数的提取器(L2)

在Scala中,没有只带一个组元的元组(这里可推测上面的提取器通常是使用元组来进行的)。如果unapply方法要提取单值,应该返回一个目标类型的Option。

提取器可以只测试其输入而不将值提取出来,此时,unapply方法应返回Boolean。

unapplySeq方法(L2)

要提取任意长度的值的序列,使用unapplySeq方法。此方法返回Option[Seq[A]],A是被提取的值的类型。


本章练习参考