2014年10月13日

scala: 關於 basic types and operations 的特殊語法

triple quote string

Java 語言在定義 String 的時候,總是會遇到一個麻煩的問題,那就是 escape,尤其是在定義 regular expression pattern 的時候,escape character 的氾濫,把原始的 String 定義破壞殆盡。

scala 借用了 erlang 的想法,引入 triple quote,用來定義使用了特殊字元的 string,非常地好用。

scala> val escapes = "\\\"\'"
escapes: java.lang.String = \"'

因為用 \ escape 會讓字串看起來很糟糕,這時候可以用 三個 " 來作為字串的開頭 & 結尾,字串中間都可以直接使用 " 或是 '。

println("""Welcome to The Maxtix.
             Type "HELP" for help.""")

在 scala cli 中測試結果為

scala> println("""Welcome to The Maxtix.
     |              Type "HELP" for help.""")
Welcome to The Maxtix.
             Type "HELP" for help.

但因為上面那個 statement 有換行,第二行前面多了一些 空白字元,為了要對齊前面,在第一與第二行最前面加上 | ,然後呼叫字串的 stripMargin。

println("""|Welcome to The Maxtix.
           |Type "HELP" for help.""".stripMargin)

在 scala cli 中測試結果為

scala> println("""|Welcome to The Maxtix.
     |            |Type "HELP" for help.""".stripMargin)
Welcome to The Maxtix.
Type "HELP" for help.

operators are methods

簡單的 sum = 1+2,其中用到了一個 + operator。

scala> val sum = 1 + 2
sum: Int = 3

但對於 scala 來說,1+2 實際上是呼叫了 (1).+(2)

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

乍看之下有點奇怪,但其實先假設 + 是一個 class 的 method: plus,因為呼叫 plus,我們必須寫成

(1).plus(2)

再把 plus 換回 + 就變成

(1).+(2)

對 scala 來說,任何 method 都可以當作 operator,s.indexOf('o') 可以寫成 s indexOf 'o'

scala> val s = "Hello, world!"
s: java.lang.String = Hello, world!

scala> s indexOf 'o'     // Scala invokes s.indexOf('o')
res0: Int = 4

scala> s indexOf ('o', 5) // Scala invokes s.indexOf('o', 5)
res1: Int = 8

unary operator

減號 - 在 scala 是一種 unary operator,就是只需要一個 operand 的 operator,他會轉換為 unary_-

scala> -2.0
res2: Double = -2.0

scala> (2.0).unary_-
res3: Double = -2.0

scala> +3
res4: Int = 3

scala> (3).unary_+
res5: Int = 3

unary+ 是相對於 unary- 而存在的,實際上 unary_+ 並沒有作任何事情。

省略的參數

如果 () 裡面沒有任何參數,就可以省略不寫

scala> val s = "Hello, world!"
s: String = Hello, world!

scala> s.toLowerCase
res0: String = hello, world!

scala> s toLowerCase
warning: there was one feature warning; re-run with -feature for details
res1: String = hello, world!

== 在 scala 跟 java 的 差異

Java 的 == 是 reference equality,兩個變數指向 heap 裡面同一個 object 。

scala 的 == 比較接近 java 的 equals,但另外提供 eq ne 這個 method 比較 reference equality。

因為 Java 的 == 同時用在 primitive data type 與 object 的比較上,因此常常會搞混。

scala 將 == 用在實際比較兩個 object 的 value,因為需要用到比較 reference 的狀況是非常少的。