1.标识符
变量、函数、类等的名称统称为标识符。
2.中置操作符
a 标识符 b,例如: 1 to 10 实际上是一个方法调用 1. to(10)
这样的表达式称作中置表达式。
3.一元操作符
只有一个参数的操作符称为一元操作符。如果它出现在参数之后,那么它就是一个后置操作符。例如:
a 标识符 等同于方法调用a.标识符()
+、-、!、~可以作为前置操作符,出现在参数之前。它们可以被转换成对名为unary_操作符的方法调用。例如:
-a 意思和 a.unary_-一样。
4.赋值操作符
赋值操作符的名称形式为操作符=,以下表达式
a 操作符=b
等同于:
a = a 操作符 b
例如: a+=b 等同于 a=a+b
关于赋值操作符,有一些技术细节要注意。
<=、>=和!=不是赋值操作符
以=开头的操作符不是赋值操作符(==、===、=/=等)
如果a有一个名为操作符=的方法,那么该方法会被直接调用
5.优先级
除赋值操作符外,优先级由操作符的首字符决定。
常见操作符的优先级:
*/%
+-
:
<>
!=
&
^
|
后置操作符的优先级低于中置操作符:
a 中置操作符 b 后置操作符 等同于 (a 中置操作符 b)后置操作符
6.结合性
在scala中,所有操作符都是左结合的,除了:
以冒号(:)结尾的操作符
赋值操作符
用于构造列表的::操作符是右结合。例如:
1::2::Nil 的意思是 1::(2::Nil)
右结合的二元操作符是其第二个参数的方法。例如:
2::Nil 的意思是 Nil.::(2)
7.apply和update方法
scala允许将如下的函数调用语法:
f(arg1,arg2,...)
扩展到可以应用于函数之外的值。如果f不是函数或方法,那么这个表达式就等同于调用
f.apply(arg1,arg2,...)
除非它出现在赋值语句的等号左侧。表达式
f(arg1,arg2,...)=value
对应如下调用
f.update(arg1,arg2,...,value)
这个机制被用于数组和映射。例如:
val scores=new scala.collection.mutable.HashMap[String,Int]
scores("Bob")=100 //调用scores.update("Bob",100)
val bobsScore=scores("Bob") //调用scores.apply("Bob")
apply方法同样被经常用在伴生对象中,用来构造对象而不用显式地使用new。例如:
class Frac(n:Int,d:Int){
...
}
object Frac{
def apply(n:Int,d:Int)=new Frac(n,d)
}
因此可以用Frac(3,4)来构造一个分数,而不用new Frac(3,4)
8.提取器
提取器是一个带有unapply方法的对象,unapply方法可以当做是伴生对象中apply方法的反向操作也可以提取任何类型对象中的提取信息。apply方法接受构造参数,然后将它们变成对象。而unapply方法接受一个对象,然后从中提取值——通常这些值就是当初用来构造该对象的值。
unapply方法通常返回一个Option,它包含一个元组,每个匹配到的变量各有一个值与之对应。例如:
object Frac{
def unapply(input:Frac)= if(input.den==0) None else Some((input.num,input.den))
}
9.带单个参数或无参数的提取器
在scala中,并没有只带一个组件的元组。如果unapply方法要提取单值,则它应该返回一个目标类型的Option。例如:
object Number{
def unapply(input:String):Option[Int]=
try{
Some(Integer.parseInt(input.trim))
}catch{
case ex:NumberFormatException=>None
}
}
这个提取器可以从字符串中提取数字:
val Number[n]="1729"
10.unapplySeq方法
要提取任意长度的值的序列,应该用unapplySeq来命名我们的方法。它返回一个Option[Seq[A]],其中A是被提取的值的类型。例如,Name提取器可以产出名字中所有组成部分的序列:
object Name{
def unapplySeq(input:String):Option[Seq[String]]=
if(input.trim=="")None else Some(input.trim.split("\\s+"))
}
这样可以匹配并提取任意数量的变量