Scala开发教程(7): 操作基本数据类型

jerry Scala 2015年11月25日 收藏

Scala提供了丰富的运算符用来操作前面介绍的基本数据类型。前面说过,这些运算符(操作符)实际为普通类方法的简化(或者称为美化)表示。比如 1+2 ,实际为 (1).+(2) ,也就是调用 Int类型的+方法。
例如:

  1. scala> val sumMore = (1).+(2)
  2. sumMore: Int = 3

实际上类Int定义了多个+方法的重载方法(以支持不同的数据类型)比如 和Long类型相加。
+符号为一运算符,为一中缀运算符。 在Scala中你可以定义任何方法为一操作符。 比如String 的IndexOf方法也可以使用操作符的语法来书写。 例如:

  1. scala> val s ="Hello, World"
  2. s: String = Hello, World
  3.  
  4. scala> s indexOf 'o'
  5. res0: Int = 4

由此可以看出运算符在Scala中并不是什么特殊的语法,任何Scala方法都可以作为操作符来使用。是否是操作符取决于你如何使用这个方法,当你使用 s.indexOf(?o?) indexOf不是一个运算符。 而你写成 s indexOf ?o? ,indexOf 就是一个操作符,因为你使用了操作符的语法。

除了类似+的中缀运算符(操作符在两个操作符之间),还可以有前缀运算符和后缀运算符。顾名思义前缀运算符的操作符在操作数前面,比如 -7的“-”。后缀运算符的运算符在操作数的后面,比如 7 toLong中的toLong. 前缀和后缀操作符都使用一个操作数,而中缀运算符使用前后两个操作数。Scala在实现前缀和后缀操作符的方法,其方法名都以unary_-开头。
比如 表达式 -2.0 实际上调用 (2.0).unary_-方法。

  1. scala> -2.0
  2. res1: Double = -2.0
  3.  
  4. scala> (2.0).unary_-
  5. res2: Double = -2.0
  6.  

如果你需要定义前缀方法,你只能使用+,-,! 和~四个符号作为前缀操作符。
后缀操作符在不使用.和括号调用时不带任何参数。在Scala中你可以省略掉没有参数的方法调用的空括号。按照惯例,如果你调用方法是为了利用方法的“副作用”,此时写上空括号,如果方法没有任何副作用(没有修改其它程序状态),你可以省略掉括号。
比如:

  1. scala> val s ="Hello, World"
  2. s: String = Hello, World
  3.  
  4. scala> s toLowerCase
  5. res0: String = hello, world
  6.  

具体Scala的基本数据类型支持的操作符,可以参考Scala API文档。下面以示例介绍一些常用的操作符:

算术运算符 + ? × /

  1. scala> 1.2 + 2.3
  2. res0: Double = 3.5
  3.  
  4. scala> 'b' -'a'
  5. res1: Int = 1
  6.  
  7. scala> 11 % 4
  8. res2: Int = 3
  9.  
  10. scala> 11.0f / 4.0f
  11. res3: Float = 2.75
  12.  
  13. scala> 2L * 3L
  14. res4: Long = 6

关系和逻辑运算符
包括 >,=,!等

  1. scala> 1 >2
  2. res5: Boolean = false
  3.  
  4. scala> 1.0 <= 1.0
  5. res6: Boolean = true
  6.  
  7. scala> val thisIsBoring = !true
  8. thisIsBoring: Boolean = false
  9.  
  10. scala> !thisIsBoring
  11. res7: Boolean = true
  12.  
  13. scala> val toBe=true
  14. toBe: Boolean = true
  15.  
  16. scala> val question = toBe || ! toBe
  17. question: Boolean = true
  18.  

要注意的是逻辑运算支持“短路运算”,比如 op1 || op2 ,当op1=true ,op2无需再计算,就可以知道结果为true。这时 op2表示式不会执行。例如:

  1. scala> def salt()= { println("salt");false}
  2. salt: ()Boolean
  3.  
  4. scala> def pepper() ={println("pepper");true}
  5. pepper: ()Boolean
  6.  
  7. scala> pepper() && salt()
  8. pepper
  9. salt
  10. res0: Boolean = false
  11.  
  12. scala> salt() && pepper()
  13. salt
  14. res1: Boolean = false
  15.  

位操作符

  1. scala> 1 & 2
  2. res2: Int = 0
  3.  
  4. scala> 1 | 2
  5. res3: Int = 3
  6.  
  7. scala> 1 ^ 2
  8. res4: Int = 3
  9.  
  10. scala> ~1
  11. res5: Int = -2
  12.  

对象恒等比较
如果需要比较两个对象是否相等,可以使用==和!=操作符

  1. scala> 1 == 2
  2. res6: Boolean = false
  3.  
  4. scala> 1 !=2
  5. res7: Boolean = true
  6.  
  7. scala> List(1,2,3) == List (1,2,3)
  8. res8: Boolean = true
  9.  
  10. scala> ("he"+"llo") == "hello"
  11. res9: Boolean = true
  12.  

Scala的==和Java不同,scala 的==只用于比较两个对象的值是否相同。而对于引用类型的比较使用另外的操作符 eq 和 ne。

操作符的优先级和左右结合性
Scala 的操作符的优先级和Java基本相同,如果有困惑时,可以使用()改变操作符的优先级。 操作符一般为左结合,Scala规定了操作符的结合性由操作符的最后一个字符定义。对于以“:”结尾的操作符都是右结合,其它的操作符多是左结合。
例如: a*b 为 a.*(b) 而 a:::b 为 b.:::(a),而 a:::b:::c = a::: (b ::: c) , a*b*c= (a*b)*c