擴展(extension)是 Swift 一個重要的特性,它可以為已存在的列舉、結構、類別和協定添加新功能,而且不需要修改該型別原本定義的程式碼。擴展也可以使用在內建的型別上,像是Int、Double或String等等。
如下所見,extension旁邊接的會是型別,而假如要接協定的話就以“:”為中介,然後開始其他的東西……
就以下例來說,擴展藉由增加計算實體屬性的方法,來增加三個計算計算實體屬性:
但要記得一件很重要事情:擴展不能新增儲存屬性,也不能為已有的屬性添加屬性觀察器(property observer)。
這個例子裡面我們針對一個整數來進行擴展:
基本上這個方法裡面傳入的值是一個閉包型別,這個例子有點好懂,反正最後就是會透過尾隨閉包的手法,將我們要讓擴展方法變成
而如果要以變異方法來做擴展的話,也是可以的,這時就要善用mutating與self的使用,在這裏,self的指稱就是回指向輸入的值,因為我們是讓輸入的值發生改變,所以一定要加上mutating。
不然就會報錯:
擴展可以為類別增加便利建構器,但指定建構器、解構器則無法新增。
在之前的篇幅中曾經提及,假若今日結構沒有定義建構器,結構會有一個自動生成的成員逐一建構器,而擴展的便利建構器對於逐一成員建構器並無影響,仍能使用。
如上例,我們在擴展了Human後,就算我們能生成一個跟name有關的字串,也不會影響在定義結構Human所產生的預設成員逐一建構器。
以下為擴展下的新增下標,這個下標主要在做的事情,是讓搜尋的數字會回傳數字字串中的數字。
擴展可以為結構、類別、枚舉新增巢狀型別,如下:
中間段的部分是這樣:
可以用case去套數字,最後會回傳星期。
接著走訪在陣列裡面裡面的數字,然後以.week的方式去把星期的內容套出來。
上述大概舉了五六種例子來說明擴展的功能:
擴展(extension)可以為已存在的列舉、結構、類別和協定添加新功能,而且不需要修改該型別原本定義的程式碼。擴展也可以使用在內建的型別上,像是Int、Double或String等等。
我們在實例裡面舉了計算屬性的擴展、方法的擴展、變異方法的擴展、建構器的擴展、下標的擴展、枚舉的擴展
但我們也可以把擴展用在協定上,這樣就不用再改動原先的擴展:
如圖,我們先定義好兩個協定,一個是正常軌道引用的協定,一個是擴展功能下的協定。
一個用正常軌道定義好了協定之後,就可以用類別來引入,然後另一個用擴展的方式處理,讓Adam也有狼叫的功能
實體化之後,Adam就是個會狼叫的人了。
鐵人賽