類和結構體是?們構建代碼所?的?種通?且靈活的構造體。我們可以使?完全相同的語法規則來為類和結構體定義屬性(常量、變量)和添加?法,從?擴展類和結構體的功能。
與其他編程語?所不同的是,Swift 并不要求你為?定義類和結構去創建獨?的接?和實現?件。你所要做的是在?個單??件中定義?個類或者結構體,系統將會?動?成?向其它代碼的外部接?。
## 一、類和結構體的對比
1、Swift 中類和結構體有很多共同點。共同處在于:
(1)定義屬性?于存儲值
(2)定義?法?于提供功能
(3)定義附屬腳本?于訪問值
(4)定義構造器?于?成初始化值
(5)通過擴展以增加默認實現的功能
(6)實現協議以提供某種標準功能
與結構體相?,類還有如下的附加功能:
(1)繼承允許?個類繼承另?個類的特征
(2)類型轉換允許在運?時檢查和解釋?個類實例的類型
(3)解構器允許?個類實例釋放任何其所被分配的資源
(4)引?計數允許對?個類的多次引?
注意: 結構體總是通過被復制的?式在代碼中傳遞,因此請不要使?引?計數。
2、定義:
類使用關鍵字class,結構體使用關鍵字struct
~~~
class SomeClass {
// class definition goes here
}
struct SomeStructure {
// structure definition goes here
}
~~~
注意: 在你每次定義?個新類或者結構體的時候,實際上你是有效地定義了?個新的 Swift 類型。因此請使?? UpperCamelCase? 這種?式來命名(如? SomeClass和 SomeStructure? 等),以便符合標準Swift 類型的?寫命名?格(如 String? , Int? 和 Bool? )。相反的,請使? lowerCamelCase? 這種?式為屬性和?法命名(如 framerate? 和 incrementCount? ),以便和類區分。
這是官方建議,但如果你非要用小寫,屬性和方法非要用大寫,那也不會出錯
下面定義一個類和一個結構體:
~~~
class PersonClass {
var name : String = ""
var age : Int = 0
var sex : String?
}
struct Dog {
var master = PersonClass()
var dogName = ""
}
~~~
除了關鍵字不一樣,看不出什么區別的
3、類和結構體實例(通常類的實例叫做類對象)
類PersonClass是描述一類人的共同屬性,并沒有具體到哪個人,所以需要一個實例來具體描述某一個人,結構體也是一樣,下面是生成實例的語法:
~~~
class PersonClass {
var name : String = ""
var age : Int = 0
var sex : String?
}
struct Dog {
var master = PersonClass()
var dogName = ""
}
let onePerson = PersonClass()
let oneDog = Dog()
~~~
4、屬性訪問:
通過使?點語法(dot syntax),可以訪問實例中所含有的屬性。其語法規則是,實例名后?緊跟屬性名,兩者通過點號(.)連接
~~~
struct Mouse {
var brand = "apple"
var price = 999.0
}
class Computer {
var mouse = Mouse()
var display = "dell"
var keyboard = "lenovo"
var mainframe = "asus"
var price = 9999.0
}
var oneMouse = Mouse()
var oneComputer = Computer()
print("the mouse brand is \(oneMouse.brand), the computer display is \(oneComputer.display)")
print("the mouse's price of the computer is \(oneComputer.mouse.price)")
oneComputer.mouse.price = 888.0
print("the mouse's price of the computer is \(oneComputer.mouse.price)")
//注意: 與 Objective-C 語?不同的是,Swift 允許直接設置結構體屬性的?屬性。
//上?的最后?個例?,就是直接設置了 oneComputer 中 oneMouse 屬性的 price 這個
//?屬性,以上操作并不需要重新設置 oneMouse 屬性。
//the mouse brand is apple, the computer display is dell
//the mouse's price of the computer is 999.0
//the mouse's price of the computer is 888.0
~~~
5、結構體類型的成員逐?構造器
所有結構體都有?個?動?成的成員逐?構造器,?于初始化新結構體實例中成員的屬性。新實例中各個屬性的初始值可以通過屬性的名稱傳遞到成員逐?構造器之中:
~~~
var twoMouse = Mouse(brand: "lenovo", price: 500.0)
print("the mouse's brand is \(twoMouse.brand), and the price is \(twoMouse.price)")
//the mouse's brand is lenovo, and the price is 500.0
~~~
與結構體不同,類實例沒有默認的成員逐?構造器
## 二、結構體和枚舉是值類型
值類型被賦予給?個變量、常量或者本?被傳遞給?個函數的時候,實際上操作的是其值的拷?
在 Swift 中,所有的基本類型:整數(Integer)、浮點數(floating-point)、布爾值(Boolean)、字符串(string)、數組(array)和字典(dictionary),都是值類型,并且都是以結構體的形式在后臺所實現
在 Swift 中,所有的結構體和枚舉類型都是值類型。這意味著它們的實例,以及實例中所包含的任何值類型屬性,在代碼中傳遞的時候都會被復制
~~~
var twoMouse = Mouse(brand: "lenovo", price: 500.0)
print("the mouse's brand is \(twoMouse.brand), and the price is \(twoMouse.price)")
//the mouse's brand is lenovo, and the price is 500.0
var threeMouse = twoMouse
threeMouse.price = 555.0
print("twoMouse price is \(twoMouse.price)")
print("threeMouse price is \(threeMouse.price)")
//twoMouse price is 500.0
//threeMouse price is 555.0
~~~
上面例子中,將twoMouse賦給threeMouse,其實就是講twoMouse拷貝一份給threeMouse,修改threeMouse中的值,twoMouse中的值并不受影響
## 三、類是引用類型
~~~
var computer1 = Computer()
print("the computer1's price is \(computer1.price)")
var computer2 = computer1
computer2.price = 1000000.0
print("the computer2's price is \(computer2.price)")
print("the computer1's price is \(computer1.price)")
//the computer1's price is 9999.0
//the computer2's price is 1000000.0
//the computer1's price is 1000000.0
~~~
與值類型不同,引?類型在被賦予到?個變量、常量或者被傳遞到?個函數時,操作的是引?,其并不是拷?。因此,引?的是已存在的實例本??不是其拷?,所以上面操作computer2的price屬性時,computer1的price屬性值也改變了,其實computer1和computer2指向同一個對象,它們操縱的也是同一個對象,這就是引用
值類型和引用類型分析如下:

1、恒等運算符
因為類是引?類型,有可能有多個常量和變量在后臺同時引?某?個類實例。(對于結構體和枚舉來說,這并不成?。因為它們作為值類型,在被賦予到常量、變量或者傳遞到函數時,其值總是會被拷?。)
如果能夠判定兩個常量或者變量是否引?同?個類實例將會很有幫助。為了達到這個目的,Swift 內建了兩個恒等運算符:
等價于 ( === )
不等價于 ( !== )
請注意 “等價于"? (?三個等號表?,===) 與 “等于"? (?兩個等號表?,==)的不同:
?? “等價于”表?兩個類類型(class type)的常量或者變量引?同?個類實例。
?? “等于”表?兩個實例的值“相等”或“相同”,判定時要遵照類設計者定義定義的評判標準,因此相?于“相等”,這是?種更加合適的叫法。
~~~
if computer1 === computer2 {
print("computer1 等價于 computer2")
} else {
print("computer1 不等價于 computer2")
}
//computer1 等價于 computer2
~~~
2、指針
在 C,C++ 或者 Objective-C 語?中,使?指針來引?內存中的地址。?個 Swift 常量或者變量引??個引?類型的實例與 C 語?中的指針類似,不同的是并不直接指向內存中的某個地址,?且也不要求你使?星號(*)來表明你在創建?個引?。Swift 中這些引?與其它的常量或變量的定義?式相同。
四、類和結構體的選擇
什么時候使用類,什么時候使用結構體呢?
按照通?的準則,當符合?條或多條以下條件時,請考慮構建結構體:
結構體的主要?的是?來封裝少量相關簡單數據值。
有理由預計?個結構體實例在賦值或傳遞時,封裝的數據將會被拷??不是被引?。
任何在結構體中儲存的值類型屬性,也將會被拷?,?不是被引?。
結構體不需要去繼承另?個已存在類型的屬性或者?為
五、字符串(String)、數組(Array)、和字典(Dictionary)類型的賦值與復制
Swift 中 字符串(String)? , 數組(Array)? 和 字典(Dictionary)? 類型均以結構體的形式實現。這意味著String,Array,Dictionary類型數據被賦值給新的常量或變量,或者被傳?函數或?法中時,它們的值會發?拷??為(值傳遞?式)
Objective-C中 字符串(NSString)? , 數組(NSArray)? 和 字典(NSDictionary)? 類型均以類的形式實現,這與Swfit中以值傳遞?式是不同的。NSString,NSArray,NSDictionary在發?賦值或者傳?函數(或?法)時,不會發?值拷?,?是傳遞已存在實例的引?
其實說白了,只要理解了什么是值類型,什么是引用類型,上面這些都很好理解。
- 前言
- swift控制語句,for,while,repeat-while,if,switch
- swift之聲明常量和變量
- swift之數值類型雜談(數值)
- swift之 元組
- oc與swift混編,OC調用swift,swift調用OC
- swift之可選類型
- swift之數組(Array)、集合(Set)、字典(Dictionary)
- swift之switch續(元組,值綁定,where)
- swift之控制轉移語句,continue,break,fallthrough,return,帶標簽的語句
- swift之函數(functions)
- swift之閉包(closure)
- swift之枚舉
- swift之類和結構體
- swift之屬性
- swift之方法(Methods)