Structs vs classes(值型別vs引用型別)

躍然發表於2015-01-06

我們知道classes是引用型別,structs屬於值型別。這就意味著,當你傳遞一個class,Swift傳遞的是物件的引用,而當你傳遞一個struct,Swift傳遞的是物件的值。

在playground寫下如下程式碼,看看它的輸出及其效果。


Structs vs classes

上面分別定義了一個結構體一個類,它們都只有一個變數。程式碼分別生成一個struct和class,並儲存它們至相應的變數中,然後分別賦值它們至第二個變數,最後程式碼改變了第二個變數的屬性。

我們可以發現,在struct示例中,只有第二個變數的foo屬性改變了,然而在class示例下,兩個變數的屬性都改變了。這就是引用型別與值型別的不同。當你把classA賦值給classB,Swift使用同樣的引用,因此,classA與classB指向同一個例項的引用。而當你將structA賦值給structB時,Swift進行了拷貝,所以現在存在兩個不同的struct。

注:Swift有copy-on-write機制,它可以機智到只有在需要的時候才拷貝struct的值。也就是說,structB=structA,不會立即進行拷貝,因為起始時候structA,structB值是相同的。只有你開始改變值了,runtime才進行拷貝處理。

為進一步描述,我們看下圖:


reference

當class、structs作為一個常量,它們有另一個細微、重要且不同的地方。

回顧我們以前學的知識,我們知道,var 和let分別定義變數和常量。當例項化為變數時,class與struct擁有一樣的行為。你可以改變它們的屬性或者賦予它們新值。當例項化為常量時候,class與structs有一些不同。下面讓我們一探究竟。

• class為常量時,你可以改變它的屬性,但不能重新賦值該常量class到其它不同的或者新的class例項中。

• struct為常量時,你不但不能賦值,就連它的屬性你也不能改變。

下圖可以演示給我們看看效果(你最好親自實踐一下,這樣印象會更深刻)


demos

因為在Swift中常量structs是完全不可改變的,這是arrays以及dictionaries之所以是structs而不是classes的原因之一。


相關文章