Swift Review#19[屬性Property-儲存屬性、計算屬性、型別屬性、屬性觀察器]補充:值型別(value type)與參考型別(reference type)

--

前言

在上一篇的文章中,有提到屬性(property)這件事情指的就是類別或結構裡面的所包含的變數、常數,而方法(method)就是類別、結構裡面的函式。

而實質上,論及屬性這件事情,有以下這四種的屬性:

  • 儲存屬性(stored property):在實體內儲存常數或變數,可以用於類別及結構。
  • 計算屬性(computed property):在實體內計算一個值,可以用於類別、結構及列舉。
  • 型別屬性(type property):與前兩個不同,這是屬於型別本身的屬性。
  • 屬性觀察器(property observer):用來觀察屬性值的變化,並以此觸發一個自定義的操作。(資料來源:Swift起步走

以下,將會分別描述這四種屬性的特質:

正文

1.儲存屬性

儲存屬性應該算是最簡單的概念,它就是可以把值存進去裡頭,比較精準的說法應該是:儲存在特定型別(類別或結構)的常數或變數。

而作為用「儲存」一詞來形容,也就意味著可變;在一開始的時候,結構或類別的設定只給定所謂的預設值、型別,然而在過程中,是可以經過修改、儲存等變動的。

如上述,在將Room404實體化後,我們便可以針對它的city這個項目來做一些內容性的更動。而這個時候打印出來的Room404的city就被改動了。

然而,上述的這個前提是建立在Room405的宣告是變數(variable)的情況,假若你今天宣稱是常數(constant),那就等著報錯吧,因為常數是無法更改的啊!:

2.計算屬性

計算屬性的功用則是不存取值,而是以get、set兩個關鍵字來存取值、或來設置其他屬性的值

get:存取值

set:設置其他屬性的值

如上述,get會做的事情就是讓值被儲存,所以可以看到右邊列跑出了130,也就是被計算的值。

而set在做的事情則是設置其他屬性的值,如上述,set( )中間傳入了leveup,而在set內部則對HP內部進行了改變,也就是上升一個等級後,它就會增加它的血量,防禦力也如是。(資料來源:Swift起步走the swift programming language

不過,關於100Days of Swift中所描述的計算屬性則有一個不一樣的例子:

總之,這個例子主要要談的內容是,我們可以創造一個屬性,這個屬性裡面可以有一些描述的計算,無論是if…else也好或whatever,它可以因此帶入內部的其他屬性進入這個屬性裡被使用,且因此從這個屬性裡輸出這個屬性的結果。

3.型別屬性(type property)

Swift起步走上對於型別屬性的描述大概是這樣:

型別屬性(type property)是屬於這個型別(類別、結構或列舉)的屬性,無論生成了多少這個型別的實體,型別屬性都只有唯一一份。

型別屬性使用於定義所有從這個型別生成的實體共享的資料。

換句話說,就是型別屬性是不變的,無論在有多少個化為實體,型別屬性會是不變的。

而型別屬性如果是儲存屬性的話,則必須有預設值,如下的armysize = 0

儲存型的型別屬性是延遲初始化的,只有在第一次被呼叫時才會被初始化,所以不需要對其使用lazy

而就以下的例子,「型別屬性是使用static關鍵字作宣告變數或常數。」

總之,我們在產出了兩個實體Tom & Leo後,我們的Armor就會自己對於其進行計算。

4.屬性觀察器

屬性觀察器這件事情很有趣,它是一個具有時間性的東西,在Swift起步走上面的描述是這樣:

屬性觀察器(property observer)會監控和回應屬性值的變化,每次屬性被設置新的值都會呼叫屬性觀察器

而屬性觀察器的建構分別由以下二者:

willSet:在設置新的值之前呼叫,會將這個新的值當做一個常數參數傳入,如果不命名這個參數名稱時,會有一個內建的參數名稱newValue

didSet:在新的值被設置之後立即呼叫,會將舊的屬性值當做參數傳入,這個參數可以自己命名,或直接使用內建的參數名稱oldValue

總和上述,didSet的用途,其實主要是就是讓新的屬性能夠被傳進去參數裡面,然後藉由值的傳入去更動整個狀態(我好像大概知道進度條要怎麼寫了XD)

而willSet則是在所有事情發生前,會有一個值被當作類似默認的存在描述。

套用100 Days of Swift的例子:

總之,上面的程式碼會打印出下面這個:

不過,據Paul Hudson認為:willSet是一個很少用的函式

但不論如何,還是來試一下willSet:

總之,在這個案例中,hp是沒有變化的,因為還沒有敘述如何讓血量減少的功能,或許往後會有機會嘗試。

補充:值型別(value type)與參考型別(reference type)

我們基本上可以知道的是:

1.結構(struct)是值型別

2.而類別(class)是參考型別

那值型別的意義是什麼呢?

其實應該歸為實務應用上的:當實體宣告其為常數的時候,它(包括裡面的常數)就都不能再更改了。

參考型別的意義則是這樣:

參考型別變數是儲存資料的參考(資料所在位址),但參考型別變數的指派會複製物件的參考,但不會複製物件的值。

也就是說,結構作為一個值型別的內容,它所宣告的內容,其實是直接連結到實際值的,類別則作為是參考型別,它所宣告的內容,其實只是參考物件,或者意思上有點像是,它就是一個幻影的概念,不會對他實質的儲存有所影響。

舉個實例來說:

實體的宣告如果改成let宣告的話就會受到影響。

但假若是class的話,就還是能打印出東西:

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

影山小麥機
影山小麥機

Written by 影山小麥機

本職為Mobile工程師,熱愛分享視野,也樂意站在ChatGPT的肩膀上。訂閱小麥機,收割技術、職涯、人生的難題。

No responses yet

Write a response