0503.偏愛欄位(Fields)不變性

欄位(Fields)的不變(val)與可變性(var)

儘可能優先考慮使用 val, 來提高不變性與函數編程風格. - WisdomFish.ORG

Scala 可以讓您自由的考量在定義一個變數對其屬性加以規定, 關鍵詞為
  1. val: 唯讀(read-only)且不可變(immutable)
  2. var: 可讀寫(read-write)或者稱為可變(mutable)


Keywords






val


物件一旦被實例化就不能再被改變, 該物件即為不可變物件,
  1. 實例內容不變性
    1. 最典型的例子 java.lang.String.
  2. 參考實例位址不變性
    1. val x = new StringBuffer( )
相當於一般稱之為非變數(non-variable), 常數(Constant), 但在 Scala 中一切均為物件型態, 故指的是參考(Reference)不可變.
  • 相當於 Java 裡的 'final' 闗鍵字效果
scala> val fish = 1
a: Int = 1

scala> fish = 2
<console>:5: error: reassignment to val
       a = 2
         ^



var


一般稱為變數(Variable), 相同的 Scala 是靜態(Static)類型編程, 雖可改變但對類型已定義而言, 重新指派的實例仍必須符合原宣告的類型.

scala> var fish = 1.0
fish: Double = 1.0

scala> fish = 1
fish: Double = 1.0

scala> fish = "Fish"
<console>:5: error: type mismatch;
found : java.lang.String("Fish")
required: Double
fish = "Fish"
^


=_ / = _

以預設值進行初始化, val 因必須在初始化時即指定 value, 故不適用.
scala> var x: String = _
x: String = null

scala> var x: Int = _   
x: Int = 0

scala> var x: Boolean = _
x: Boolean = false

scala> var x: Double =_ 
x: Double = 0.0

scala> var x: Float =_ 
x: Float = 0.0

scala> var x: Long =_ 
x: Long = 0

scala> var x: Short =_
x: Short = 0

scala> var x: Short   
<console>:5: error: only classes can have declared but undefined members
(Note that variables need to be initialized to be defined)
       var x: Short
           ^

scala> class X {
     | var x: Int
     | var x1: String
     | }             
<console>:5: error: class X needs to be abstract, since:
variable x1 is not defined
(Note that variables need to be initialized to be defined)
variable x1 is not defined
(Note that variables need to be initialized to be defined)
variable x is not defined
(Note that variables need to be initialized to be defined)
variable x is not defined
(Note that variables need to be initialized to be defined)
       class X {
             ^

scala> class X(var x: Int, var z: String) 
defined class X
                       
scala> val x = new X(2, "H")
x: X = X@3b39d369





lazy val


變數的延遲初始化
  • call-by-name:當方法內容第一次使用到外部指定名稱的變數, 才對該變數進行初始化計算
scala> lazy val fish = 10
fish: Int = <lazy>

scala> print(fish)       
10


def If[X](b: => Boolean)(x: => X)(y: =>X) = if(b) x else y





References


Comments