2016年4月8日 星期五

[Scala 小學堂] Scala Gossic : 起步走 - 資料、變數、操作 (變數, 常數)

轉載自 這裡 
前言 : 
Scala 是一個可直譯、可編譯、靜態、可運行於 JVM 之上、可與 Java 互操作、融合物件導向編程特性與函式編程風格的程式語言. 從一些簡單的語法開始,了解 Scala 的許多特性,所以就算是起步走,東西也夠多了. 簡單的小程式可以使用 scala 指令,編譯的事就交給 scalac,編譯想快點就用 fsc. (Scala 官網), 所有的東西都是物件,所有的操作都是方法. 

變數, 常數 : 
如果你要宣告一個變數(Variable),在Scala中可以使用 var 或 val 來宣告,底下是個用 val 宣告的例子 : 
scala> val sum:Int = 1 + 2
sum: Int = 3

scala> val text:String = "Hello"
text: java.lang.String = Hello

scala> val scores:Array[Int] = Array(80, 90, 100)
scores: Array[Int] = Array(80, 90, 100)


Scala 是個靜態(static type)語言,由變數帶有型態資訊,以上的示範中,sum 是變數名稱,Int 是其型態,text 是變數名稱,型態為 String,而 scores 是變數名稱,型態為 Array[Int]陣列中內含Int元素). 這冗長的宣告方式確實是宣告變數的完整型式,但事實上,它可以使用以下的方式宣告 : 
scala> val sum = 1 + 2
sum: Int = 3

scala> val text = "Hello"
text: java.lang.String = Hello

scala> val scores = Array(80, 90, 100)
scores: Array[Int] = Array(80, 90, 100)


畢竟從值的指定來看,1 + 2 結果會是 Int,"Hello"則是個 String,第三行也可以知道是個 Array在某些情況下,若Scala可以由陳述句中,推斷出變數的型態,則無需在變數上重複宣告類型,這是Scala的類型推斷(type inference)特性在 Scala 中,由 val 宣告的變數,一旦指定值,就不可以再重新指定別的值給它,例如以下會有錯誤訊息 : 


如果你希望所宣告的變數在指定值之後,稍後在其它地方也可以再設定新的值給它,則要使用 var 宣告 : 
scalavar sum = 1
sum: Int = 1

scala> sum = 2
sum: Int = 2

Scala 鼓勵你使用 val 來宣告變數,Scala 認為在演算流程中修改變數的值,會造成程式邏輯的複雜性與不易維護,使用 var 宣告變數時通常就是一種訊號,表示你可能使用了 imperative 風格的撰寫方式,Scala 鼓勵你使用 functional 風格的撰寫方式,也支援撰寫 functional 風格程式碼的一些特性不可變動物件、函式物件、模式比對等,之後會一一介紹). 使用 var 宣告值,除了在類別定義中作為資料成員外(預設為null),都必須明確給定值給它,否則會發生錯誤,若不知道值為何,至少要設為 null : 


當你將長度較小的資料型態(例如 Int)指定給長度較大的資料型態(例如 Long),這樣的指定在精確度並不會失去,所以這樣的指定是可行的,但你將長度較大的指定給較小的,就會發生問題 : 
 

在 Scala 中要進行轉型(Cast),可以使用 asInstenceOf,但對於數值,更方便的作法是直接呼叫 toXXX 方法,例如 : 
scala> var x = 1
x: Int = 1

scala> var y = 2L
y: Long = 2

scala> x = y.asInstanceOf[Int]
x: Int = 2

scala> x = y.toInt
x: Int = 2


有個有趣的事是,Scala 在宣告變數名稱時,可以使用 Unicode 編碼(雖然不鼓勵這麼用),例如 : 
scala> val \u0073\u0075\u006D = 10
sum: Int = 10


在 Scala 中,建議使用駝峰式(Camel case)的命名方式,也就是變數名稱首字小寫,之後每遇到單字首字大寫,例如像 scoreOfStudent 這樣的名稱. 在Scala中雖然可以使用 _ 作為變數名稱的字元,例如 score_of_student 這樣的名稱,但不建議使用 _ 作為名稱的一部份,因為在 Scala 的處理中,會使用一些有底線字元的名稱,如果你的變數名稱湊巧使用了相同的名稱,使得 Scala 混淆了,可能會有一些無法預期的錯誤. 同樣的,在Scala中也可以使用$作為名稱的一部份,但不建議使用,因為$是Scala處理中一些內部名稱的表示方式(例如編譯器產生的識別字). 

再來看常數(Constant)的定義,常數顧名思義就是不變的數,不過若你要在Scala中定義一個常數,不僅僅是使用 valval 所宣告的變數,其意義其實是指設定值給它後,就不能再指定值給它,但還是個變數,例如 : 
  1. def doSome(x: Int) {  
  2.     println(x)  
  3. }  
上 面這個例子,在Scala中定義一個函式(function),其中 x 是呼叫時接收引數的參數名稱,在 Scala 中參數一定是 val只是你不用特別加上 val 宣告,不過要加也可以,只是寫來冗長)。但事實上,每次你呼叫函式傳入引數不同,x 的值也就不同,所以它還是變數(只是在 doSome 函式中不可重 新指定值). 常數的定義,是指那些恒常不變的值,至少在整個程式運行過程中是如此,例如圓周率就是3.141596...這樣的值,或者是你在程式運行過程中絕不改變的值。在 Scala 中,對於常數值,所採用的命名慣例是首字大寫,之後可以是的駝峰式寫法,例如 scala.math 中就定義了 Pi 表示圓周率,也可以是像 scala.math 中 MAX_INT 這樣的寫法,這比較符合 Java 開發人員的慣例,不過 Scala 鼓勵使用首字大寫的駝峰式寫法(其實這不僅是慣例,在模式比對時,有利用到這樣的常數寫法之特性). 在 Scala 中,還可以將變數名稱包括在`與`(標記號,也就是~符號鍵下方看似單引號的符號)之間,例如 : 
val `x` = 10


這個機制的利用時機,可以像是這樣 : 



yield 在Scala中是保留字,如果你非得在 Scala 中使用 yield 這個名稱,就可以使用 `` 來包括它。例如以下的範例中,你不可以直接呼叫 Thread.yield(),而要改用 Thread.`yield`() : 


補充說明 : 
思考函數編程(一)Language is Functional Again 

什麼是物件導向編程(OOP)?只要你寫過幾年程式,如果你沒太混的話,一定說得出「封裝、繼承、多型」這三個術語。什麼是函數編程(Functional Programming,FP)?即使你寫了很多年的程式,應該也是答不出來,大家對它相當陌生,少有人能正確地敘述出函數編程是什麼,有什麼好處。某些人或許只能空泛地回答:「我聽說函數編程…」,但口氣卻仍不甚堅定...

Tutorialspoint - Scala Variables

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...