Structs vs classes(值型別vs引用型別)
我們知道classes是引用型別,structs屬於值型別。這就意味著,當你傳遞一個class,Swift傳遞的是物件的引用,而當你傳遞一個struct,Swift傳遞的是物件的值。
在playground寫下如下程式碼,看看它的輸出及其效果。
上面分別定義了一個結構體一個類,它們都只有一個變數。程式碼分別生成一個struct和class,並儲存它們至相應的變數中,然後分別賦值它們至第二個變數,最後程式碼改變了第二個變數的屬性。
我們可以發現,在struct示例中,只有第二個變數的foo屬性改變了,然而在class示例下,兩個變數的屬性都改變了。這就是引用型別與值型別的不同。當你把classA賦值給classB,Swift使用同樣的引用,因此,classA與classB指向同一個例項的引用。而當你將structA賦值給structB時,Swift進行了拷貝,所以現在存在兩個不同的struct。
注:Swift有copy-on-write機制,它可以機智到只有在需要的時候才拷貝struct的值。也就是說,structB=structA,不會立即進行拷貝,因為起始時候structA,structB值是相同的。只有你開始改變值了,runtime才進行拷貝處理。
為進一步描述,我們看下圖:
當class、structs作為一個常量,它們有另一個細微、重要且不同的地方。
回顧我們以前學的知識,我們知道,var 和let分別定義變數和常量。當例項化為變數時,class與struct擁有一樣的行為。你可以改變它們的屬性或者賦予它們新值。當例項化為常量時候,class與structs有一些不同。下面讓我們一探究竟。
• class為常量時,你可以改變它的屬性,但不能重新賦值該常量class到其它不同的或者新的class例項中。
• struct為常量時,你不但不能賦值,就連它的屬性你也不能改變。
下圖可以演示給我們看看效果(你最好親自實踐一下,這樣印象會更深刻)
因為在Swift中常量structs是完全不可改變的,這是arrays以及dictionaries之所以是structs而不是classes的原因之一。
相關文章
- 【C#之值型別vs引用型別】C#型別
- 值型別和引用型別型別
- 值型別與引用型別型別
- 型別 VS 泛型型別泛型
- JavaScript值型別和引用型別JavaScript型別
- c#:值型別&引用型別C#型別
- Swift值型別和引用型別Swift型別
- 值型別與引用型別的區別型別
- C#的型別——值型別與引用型別C#型別
- JavaScript - 基本型別與引用型別值JavaScript型別
- Go for PHP Developers: Structs vs Classes (翻譯)GoPHPDeveloperStruct
- C# 物件比較(值型別、引用型別)C#物件型別
- C#變數型別(1):引用型別和值型別 (轉)變數型別
- 區別值型別資料和引用型別資料型別
- C# 泛型 引用型別約束 值型別約束C#泛型型別
- Swift 中的值型別與引用型別使用指北Swift型別
- 從賦值看基本型別和引用型別的區別賦值型別
- Python引用型別和值型別的區別與使用Python型別
- javascript原始值和引用值型別及區別JavaScript型別
- 基本資料型別和引用型別的初始值資料型別
- JavaScript引用型別-Object型別JavaScript型別Object
- C#程式設計引用型別和值型別 以及引用傳遞和值傳遞C#程式設計型別
- VS中”LPTSTR" 型別的值不能用於初始化 "char *" 型別的實體型別
- 引用型別型別
- 33 個 JavaScript 核心概念系列(二): 值型別與引用型別JavaScript型別
- C#學習筆記之值型別與引用型別C#筆記型別
- JavaScript 值型別和引用型別在堆疊中的存放JavaScript型別
- ECMAScript 原始型別與引用型別型別
- javascript基本型別 引用型別 基本包裝型別JavaScript型別
- js基本型別和引用型別區別JS型別
- JAVA 基本型別與 引用型別區別Java型別
- golang中 值型別,指標,引用的區別Golang型別指標
- 圖解C#的值型別,引用型別,棧,堆,ref,out圖解C#型別
- Java的基本型別和引用型別Java型別
- 問題分享:Js引用型別賦值JS型別賦值
- Golang的值型別和引用型別的範圍、儲存區域、區別Golang型別
- js引用型別JS型別
- javascript:引用型別JavaScript型別