Class和Struct是Swift中很重要的兩種數據結構,同時也是Swift面試題必問的一道題。因此對Class和Struct理解透徹對咱們學習Swift有很大的幫助。html
class Animal {
var name: String?
var weight = 0.0
}
let cat = Animal()
cat.name = "cat"
cat.weight = 10
print("cat's name: \(cat.name!), cat's weight: \(cat.weight)") //cat's name: cat, cat's weight: 10.0
複製代碼
當值傳遞的時候,它是傳遞對已有instance的引用。下面用代碼來解釋一下這句話:面試
let cat = Animal()
cat.name = "cat"
cat.weight = 10
let blackCat = cat
blackCat.name = "blackCat"
print("cat's name: \(cat.name!)") // cat's name: blackCat 複製代碼
經過上面的代碼能夠了解到,其實cat
和blackCat
指向的是同一個Animal的instance。它們只是這個instance的兩個不一樣的名字而已。以下圖所示:swift
咱們看到上述代碼把cat
和blackCat
聲明爲了let
,可是咱們依然能夠修改它的屬性,由於cat
和blackCat
引用的instance並無改變,它們仍是引用以前instance,咱們只是修改的instance的屬性。可是不能將cat
或者blackCat
指向另外一個實例,如blackCat = Animal()
會提示Cannot assign to value: 'blackCat' is a 'let' constant
的錯誤。bash
Swift 提供===
和!==
來判斷兩個變量或者常量是否是引用同一個instance(只用於class,想想爲何struct不須要).數據結構
if blackCat === cat {
print("Identical") //Identical
} else {
print("Not identical")
}
複製代碼
===
和==
是不同的。===
:表明兩個變量或者常量引用的同一個instance==
:表明兩個變量或者常量的值是否相同,並不必定是引用的同一個instance==
操做符,可使該類遵照Equatableclass Animal {
var name: String?
var weight = 0.0
}
extension Animal: Equatable {
static func == (lhs: Animal, rhs: Animal) -> Bool {
return lhs.name == rhs.name && lhs.weight == rhs.weight
}
}
let cat = Animal()
cat.name = "cat"
cat.weight = 10
let blackCat = cat
blackCat.name = "catName"
let whiteCat = Animal()
whiteCat.name = "catName"
whiteCat.weight = 10.0
if blackCat === cat {
print("Identical") //Identical
} else {
print("Not identical")
}
if whiteCat === blackCat {
print("Identical")
} else {
print("Not identical") //Not identical
}
if whiteCat == blackCat {
print("Equal")
} else {
print("Not Equal") //Equal
}
複製代碼
struct FPoint {
var x = 0.0
var y = 0.0
//當在struct修改屬性的時候須要使用mutating
mutating func addX(add: Double) {
self.x = self.x + add
}
}
let p1 = FPoint()
print("p1's x : \(p1.x), p1's y: \(p1.y)") // p1's x : 0.0, p1's y: 0.0
複製代碼
當值進行傳遞的時候,它會copy傳遞的值。下面用代碼來解釋一下這句話:多線程
var p2 = p1
p2.x = 3.0
print("p1's x : \(p1.x), p1's y: \(p1.y); p2's x : \(p2.x), p2's y: \(p2.y)")
//p1's x : 1.0, p1's y: 2.0; p2's x : 3.0, p2's y: 2.0
複製代碼
經過上述代碼咱們能夠看到,將p1
賦值給p2
以後改變p2
的值並不會影響p1
的值,這是由於在將p1
賦值給p2
的時候是拷貝一個instance值與p1相同
,而後將拷貝的instance賦值給p2
。以下圖所示:app
若是struct的instance聲明爲let,是不能改變instance的值的。如ide
let p1 = FPoint(x: 1.0, y: 2.0)
p1.x = 10.0 //報錯:Cannot assign to property: 'p1' is a 'let' constant
複製代碼
protocol AnimalCommonProtocol {
var name: String? { get set }
var weight: Double { get set }
func run()
}
struct Cat : AnimalCommonProtocol {
func run() {
print("cat run")
}
var name: String?
var weight: Double
var gender: String?
}
struct Dog : AnimalCommonProtocol {
func run() {
print("dog run")
}
var name: String?
var weight: Double
var type: String?
}
複製代碼
總結起來就是一句話:能使用struct就不要使用class學習
mutating
關鍵字;struct須要