Swift:10 類和結構體
類和結構體是Swfit語言的核心內容之一。在Swfit中類和結構體有很多相同的特性,比如都有屬性、方法、下標、構造器、擴展和協議等特性,同時,類又有結構體所不具有的特性:繼承、類型轉換、析構和引用計數等。跟Objective-C相比,Swift中的類沒有.h頭文件。
類和結構體基本用法
類和結構體的定義語法相似。通過關鍵詞class來引入一個類,通過struct關鍵詞來引入一個結構體。他們的定義都在一對花括號中:
struct point{
var x:Int = 0
var y:Int = 0
}
class map {
//可選類型的屬性
var name:String?
var po = point()
}
使用類或者結構體名后面加上括號"()",就可以調用它們的構造函數來對類或結構體進行實例化??梢酝ㄟ^在實例后面加上點”.“語法來訪問類和結構體的屬性。所有結構體都有一個自動生成的成員構造器( memberwise initializer),可以用來初始化新的結構體實例的成員屬性。新的實例的初始值可以通過名字傳遞給成員構造器。
struct point{
var x:Int = 0
var y:Int = 0
}
class map {
//可選類型的屬性
var name:String?
var po = point()
}
//成員構造器
var p1 = point(x:10,y:20)
var m1 = map()
m1.name = "地圖1"
m1.po = p1
print("\(m1.name!)中的po的坐標點是(\(m1.po.x),\(m1.po.y))")
//打印結果:地圖1中的po的坐標點是(10,20)
結構體和枚舉是值類型
Swift中所有的基礎類型,比如整數、浮點數、布爾值、字符串、數組和字典的類型都是值類型,所有的結構體和枚舉也都是值類型,也就是說在代碼中傳遞的時候,結構體和枚舉實例以及他們的值類型的屬性都會被復制。
enum color{
case R,G,B,A
}
struct point{
var x:Int = 0
var y:Int = 0
}
var c1 = color.R
var c2 = c1
c2 = .G
if c1 == color.R {
print("枚舉是值傳遞")
}
var p1 = point(x:10,y:10)
var p2 = p1
p2.y = 20
print("p1的坐標是(\(p1.x),\(p1.y))")
print("p2的坐標是(\(p2.x),\(p2.y))")
代碼運行結果如下圖。
類是引用類型
跟Objective-C中的類一樣,Swift中的類是引用類型。比較兩個引用類型是否相等的運算符是恒等(===)和(!==)不恒等。
class map {
//可選類型的屬性
var name:String?
}
var m1 = map()
m1.name = "地圖1"
var m2 = m1
m2.name = "地圖2"
if m1 === m2 {
print("m1恒等于m2")
}
print("m1.name = \(m1.name!),m2.name=\(m2.name!)")
//打印結果:m1恒等于m2
// m1.name = 地圖2,m2.name=地圖2
如何選擇類和結構體
一般地,在滿足如下的一個或幾個條件的情況下使用結構體:
- 封裝一些相關的簡單的數據值
- 有必要通過副本而非引用來賦值或者傳遞
- 所有屬性本身是值類型,也是用來復制而非引用
- 不需要從已有類型集成屬性或者行為
除以上幾種情況外,基本上都選擇類來構建數據類型。
集合類型的賦值和拷貝行為
Swift中,Array和Dictionary類型是按照結構體實現的。也就是說當把數組和字典以及其他的結構體賦值給常量或者變量以及傳遞給函數或者方法時會發生值拷貝的行為。
和Foundation中的NSArray以及NSDictionary不一樣(他們是類實現),NSArray和NSDictionary實例始終是按照引用賦值和傳遞的,而不是拷貝。
示例代碼
https://github.com/99ios/23.11