自訂型態

有時候我們會覺得電腦所給予的資料型態太少,想要一些特別的型態來適合一些特定場合,例如在電腦領域裡的「顏色」可以由RGB數值、HSV數值或者CMYK數值來表達,在小畫家這個軟體裡面,這些數值都是Int整數,像紅色這個色彩是這樣的:

// 創建一個名為 red 的紅色給電腦
// 在小畫家中,它的 RGB 數值分別是 (255, 0, 0),我們因此將它存在三個整數常數裡面
let red_R = 255
let red_G = 0
let red_B = 0

現在我們想要使用這個顏色時,儘管這只是一個顏色,卻必須在程式碼裡面提到這三個常數才行!甚至我們如果要計算兩個顏色的相加或相乘,更是完全傻眼了,程式碼到底要怎麼寫?就算你有想出寫法好了(做得不錯!),它也不是很容易用一行程式碼達成的。

要是電腦認得「顏色」這種型態,也知道怎麼去計算相加或相乘(例如藍色+橘色),不是太好了嗎?

這有可能做到嗎?完全是可以做到的!我們以一個比較簡單的物件:直角座標系上的座標為例。

struct 座標 {
    var x:Int
    var y:Int
}

這段程式碼告訴了電腦,我們要宣告一個資料型態,它叫做「座標」,{}包裹的程式碼,都屬於這個「座標」資料型態的內容,「座標」裡面有兩個整數型態的變數,分別叫做xy。(我們要用它來儲存一個點的 x 座標和 y 座標)

做了這樣的宣告之後,我們就可以用類似建立整數、小數、字串物件的方式來建立我們自己的資料型態。

let a:座標

那麼要怎麼使用它呢?這邊要介紹一個新的觀念:.,這個點的用處是取得一個資料裡的某個屬性,或者執行一個資料裡的某種指令,它的概念有點像這樣:

let 教主:人類           // 宣告一個人類型態的物件,名稱是教主
print(教主.身高)        // 列印教主的身高
教主.玩遊戲()           // 讓教主去玩遊戲

聰明的你或許看到這裡,就開始在模擬器裡面玩耍了...

let a:座標
a.x = 1
a.y = 2

於是電腦很迅速地回報了錯誤:

Swift:: Error: struct 'a' must be completely initialized before a member is stored to
a.x = 1
    ^

這是什麼意思呢?自訂型態struct有一個和IntFloatDoubleString這些型態最大的差異,就是它有可能不能用單一個資料型態表達(以座標為例,它要xy同時有值時才有意義),因此電腦限定自訂型態必須經過「初始化」這個重要的步驟,為裡面所有使用到的資料賦予一個值,之後才能開始使用這個自訂型態。

(想像一下一個座標有x值,卻沒有y值,它到底在哪裡?它有意義嗎?運算起來會發生什麼問題?)

要達成初始化有兩種方法,分述如下:

struct 座標 {
    var x:Int = 0          // 預設 x = 0
    var y:Int = 0          // 預設 y = 0
}
let a:座標 = 座標()         // a是座標(x:0, y:0)這樣的物件
let b:座標 = 座標(x:5, y:5) // b是座標(x:5, y:5)這樣的物件
struct 座標 {
    var x:Int        // 沒有預設值
    var y:Int        // 沒有預設值
}
let a:座標 = 座標()         // 電腦報錯,因為沒有預設值
let b:座標 = 座標(x:5, y:5) // b是座標(x:5, y:5)這樣的物件
如果x有預設值,y沒有預設值,會發生什麼事?試試看!

一旦經過初始化之後,就可以正常使用a.x或者a.y去取得它們相對應的值了,以後或許我們會撰寫程式碼來計算座標與向量的相加,或者座標的旋轉等等不同的功能,它們將可以直接對「座標」物件操作,而不必拆成兩個整數分別做一堆運算,程式碼將會整潔、一目了然許多,這些都是自訂資料型態struct的好處!

results matching ""

    No results matching ""