前言
和其他語言不同的是,Swift不需要為自定義的類和結構體創建接口和實現文件。只需要創建單一文件用來創建類和結構體,其他的外部接口的代碼系統會自動生成。下面這篇文章主要介紹了關于Swift 3.0類與結構體的內容,感興趣的朋友一起來看看吧。
類和結構體區別
Swift的類和結構體具有以下相同的特點:
- 可以定義屬性來保存值
- 可以定義方法來提供功能
- 可以定義下標來使用他們的值
- 可以定義初始化器來配置他們的初始化狀態
- 可以在默認的實現上擴展他們的功能
- 遵從協議來提供標準的功能
類具有結構體沒有的額外的功能:
- 繼承允許某一個類繼承另外一個類的特性
- 類型轉換允許你檢查并在運行時解釋一個類實例的類型
- 析構器允許釋放所有該類已經賦值的實例資源
- 引用計數允許多個引用一個類的實例
結構體一般來說賦值的時候是直接拷貝的,沒有使用引用計數的機制。
符號定義
下面是一個定義結構體和類的例子:
1
2
3
4
5
6
7
8
9
10
|
struct Resolution { var width = 0 var height = 0 } class VideoMode { var resolution = Resolution() var interlaced = false var frameRate = 0.0 var name: String? } |
結構體初始化的時候可以直接
1
|
let vga = Resolution(width: 640, height: 480) |
這點和類不一樣,類沒有默認的逐個成員的初始化器。
結構體和枚舉是值類型
1
2
|
let hd = Resolution(width: 1920, height: 1080) var cinema = hd |
再賦值
1
|
cinema.width = 2048 |
結果
1
2
|
print( "cinema is now \(cinema.width) pixels wide" ) // Prints "cinema is now 2048 pixels wide" |
然而hd.width還是1920
1
2
|
print( "hd is still \(hd.width) pixels wide" ) // Prints "hd is still 1920 pixels wide" |
可見賦值過程是做了一次深度拷貝。
枚舉也是具有同樣的行為, 如以下例子,rememberedDirection的值并沒有改變:
1
2
3
4
5
6
7
8
9
10
|
enum CompassPoint { case north, south, east, west } var currentDirection = CompassPoint.west let rememberedDirection = currentDirection currentDirection = .east if rememberedDirection == .west { print( "The remembered direction is still .west" ) } // Prints "The remembered direction is still .west" |
類是引用類型
例如:
1
2
3
4
5
|
let tenEighty = VideoMode() tenEighty.resolution = hd tenEighty.interlaced = true tenEighty.name = "1080i" tenEighty.frameRate = 25.0 |
進行賦值引用
1
2
|
let alsoTenEighty = tenEighty alsoTenEighty.frameRate = 30.0 |
結果
1
2
|
print( "The frameRate property of tenEighty is now \(tenEighty.frameRate)" ) // Prints "The frameRate property of tenEighty is now 30.0" |
標識符
- 完全相同(===)
- 不完全相同(!===)
1
2
3
4
|
if tenEighty === alsoTenEighty { print( "tenEighty and alsoTenEighty refer to the same VideoMode instance." ) } // Prints "tenEighty and alsoTenEighty refer to the same VideoMode instance." |
完全相同(===)和等于(==)是不一樣的:
- 完全相同意思是兩個類類型的常量或者變量指向完全相同的類實例
- 等于意思是兩個實例被認為值相同或者相等, 可以自行定義==操作符來進行判斷兩個實例在某種意義上是相等的
選擇使用類和結構體
由于結構體的實例一般是值傳遞,而類實例一般是引用傳遞,因此你需要根據實際情況來考慮應該定義一個類還是結構體.
如有以下一種或多仲情況使用結構體:
- 結構體主要的目的是封裝少量的相關性簡單數據值
- 在結構體的實例賦值或者傳遞的時候,需要考慮到封裝好的值會被拷貝而不是引用是否是合理的
- 任何保存于結構體的屬性都是值類型的,他們也是期望被賦值或者傳遞時是拷貝而不是引用
- 結構體不需要從其他存在的類型繼承屬性或者行為
看看幾個使用結構體恰當的例子:
- 幾何圖形的大小,可以封裝width和height屬性,都是Double類型
- 指向連續序列范圍的方法,可以封裝start和length屬性,都是Int類型
- 一個在3D坐標系統的點, 可以封裝x, y和z屬性,都是Double類型
其他的情況請定義類并創建類實例,管理和傳遞都使用引用。
在實踐中,大部分的自定義數據結構都是使用類居多,很少使用結構體。
String、Array和Dictionary的賦值和拷貝行為
String, Array和 Dictionary都是結構體,因此賦值直接是拷貝,而NSString, NSArray 和NSDictionary則是類,所以是使用引用的方式。
參考英語原文:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/ClassesAndStructures.html#//apple_ref/doc/uid/TP40014097-CH13-ID82
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:http://devlong.com/2016/11/02/swift-classes-and-structures/