Structure of Class?

struct Rect {
   var origin: Point
   var size: Size

   var area: Double {
       return size.width * size.height
   }
}

class Window {
  var frame: Rect
  ...
}

既然 structureclass 長得這麼像(看上述程式碼超像),什麼時候要用 structure,什麼時候要用 class 呢?

StructureClass 有兩個最大的不同:

  1. Structure 不能被其他的 structure 繼承。
  2. Structure instance 與 class instance 參數傳遞的方式不同。

第 1 點很清楚了,以下就第 2 點加以說明:

Class Instances are Passed by Reference

先用 class 舉例,假設我們有一個 Window 的物件 (instance),window

var window = Window(frame: frame)

用示意圖表示就會像這樣:

Screen Shot 2014-06-07 at 3.14.17 PM.png


接著我們想對 window 做設定,因此我們自己宣告一個 setUp() 的 function,把 window 當參數傳進去:

var window = Window(frame: frame)

setUp(window)

func setUp(window: Window) {
   // do some setup
}

照正常的想法來說,我們把 window 傳到 setUp() 做設定,設定的是同一個 window,而不是要 setUp() copy 一個新的 window,以下 不是 我們想要看到的:

Screen Shot 2014-06-07 at 3.13.53 PM.png

這不是我們想要的,我們想要編輯同一個 Window 物件 (instance)。


實際的 setUp() 是下面這種情況:

Screen Shot 2014-06-07 at 3.21.20 PM.png

setUp()中編輯的 window 就等於從外面傳進來 window (Reference 到同一個 instance)。因此我們可以知道,當我們把 class 物件(instance)當做參數傳遞時,被修改的都是同一個物件(instance)。

由此可知: Class Instances are Passed by Reference

Structures are Passed by Value

假設我們想得到 windowframe,我們宣告 newFrame

var newFrame = window.frame

此時我們去修改 newFrame 的值:

newFrame.origin.x = 20.0

這樣會改變 window.frame 的值嘛? 不會

newFrame 是一個全新的物件(instance),跟 window.frame 沒有任何關係,只有內容相同而已。也就是說: window.frame copy 了一份一模一樣的內容給 newFrame

由此可知: Structures are Passed by Value


以上的說明,我們就知道大概的區別:

  • 想要操作同一個物件(instance)時,就宣告 class
  • 想要每次都是 copy 一份新的物件(instance)時,就使用 structure

下一篇: Constants and Variables