Scala从零起步:运算符
导读
继续Scala从零起步系列,在前文分享变量和标识符的基础上,本文介绍Scala中的运算符。简单地说,Scala中的运算符和其他编程语言中的运算符并无太大区别,更多都是相同或者相近的,但是出于系列文章的内容完整性,仍然单开此文对其予以介绍。
如同多数编程语言中的那样,Scala中的运算符可概括为:
数学运算符
关系运算符
逻辑运算符
位运算符
特殊运算符
数学运算符是最为常规和常用的运算符,主要包括四则运算以及模余共5类运算,运算符表达方式也与其他编程语言保持一致:分别采取+、-、*、/、%来表示。唯一值得一提的是除法运算中,如果分子分母均为整数,则结果仍然保留整数,只有当分子和分母中有小数参与时才得到通常意义下的商。
scala> 5 / 2
val res0: Int = 2
scala> 1.0 * 5 / 2
val res1: Double = 2.5
也如同其他编程语言中的关系运算符那样,Scala中的关系运算符主要包括6类:>、>=、<、<=、==、!=。其中大于和小于类的4个运算符属于常规运算符,除了可用于比较数值类大小外,也可用于比较字符串大小。同时需要注意==和!=两个运算符,判断两个对象是否相等的底层逻辑有些许区别:当调用运算符的对象为null时,底层调用eq方法,否则调用equals方法。这里eq方法和equals方法的区别在于前者判断引用是否相等,而后者仅判断字面值是否相等。
scala> "AB" > "AA" // >也适用于字符串比较
val res2: Boolean = true
scala> val s = "string"
val s: String = string
scala> s == s+"" // s非空,所以调用equals方法,判断值相等
val res3: Boolean = true
scala> s.equals(s+"") // 判断值相等
val res4: Boolean = true
scala> s.eq(s+"") //判断引用相等,由于此时s+""对应新的地址,所以不等
val res5: Boolean = false
Scala中的逻辑运算符基本保持了C和Java中的风格,即分别用&&、||以及!表达与或非。其中与或非具有短路特性,即已经可以判断出最终结果时则不再判断后续表达式。
scala> val i = 0
val i: Int = 0
scala> if(i!=0 && 3/i>1) "a" else "b" // 避免除数为0引发异常
val res6: String = b
位运算符是整数特有的运算操作符,Scala中主要包括6类7个运算符:分别是按位与、按位或、按位异或、按位取反以及左移位符和右移位符,其中前5类运算符依次用&、|、^、~、<<表示,而右移位符因其特殊性,又细分为>>和>>>两种右移位符,其中前者是保留符号右移,而后者则是无符号右移位,即右移之后顺序填充0,所以可能将负数通过右移变为正数。
scala> -1 << 1
val res7: Int = -2
scala> -1 >> 1
val res8: Int = -1
scala> -1 >>> 1
val res9: Int = 2147483647
前面4类运算符大多较为中规中矩,与其他编程语言中的相应运算符差别不大,自然也比较好理解。下面介绍Scala中的几个特殊运算符(严格来讲也可不称之为运算符,或许叫做方法更为严谨),非常具有Scala特色:
:,即英文冒号(一般读作cons,代表连接的意思),适用于数组Array和列表List的连接操作。在Scala中,但凡以:结尾的运算符,那么都是右操作数的运算符,即应:右侧的操作数为基准进行相应计算。较为常见的包括4个:即:+、+:、::、:::,其相应含义如下:
scala> val list = List(1, 2)
val list: List[Int] = List(1, 2)
scala> list :+ 3 // 在列表右端连接新的元素
val res10: List[Int] = List(1, 2, 3)
scala> 3 +: list // 在列表左端连接新的元素
val res11: List[Int] = List(3, 1, 2)
scala> 3 :: list // 在列表左端连接新的元素
val res12: List[Int] = List(3, 1, 2)
scala> list ::: List(3) // 两个列表元素进行拼接
val res13: List[Int] = List(1, 2, 3)
->:字典映射运算符,即用于构造字典key-value的映射关系。更进一步地,由于Scala中的字典元素本质上是一个二元组,所以由->连接的两个值也会被解释器理解为tuple2
scala> val map = Map("a"->1, "b"->2)
val map: scala.collection.immutable.Map[String,Int] = Map(a -> 1, b -> 2)
scala> 1->2
val res14: (Int, Int) = (1,2)
<-:迭代赋值运算符,类似于Python中in的作用,一般用于将<-右侧的可迭代对象逐元素赋予左侧的变量,从而完成循环遍历,配合for使用尤为好用
scala> for(i <- List.range(1, 5)) println(i)
1
2
3
4
=>,定义函数映射。主要用在定义函数过程中,衔接参数列表与函数体之间的符号,表示映射关系。理论上不属于运算符,但仍在此处加以提及。
相关阅读: