Swift協議和擴展
協議
與OC中一樣,協議的關鍵字也是protocol
在Swift中,class(類)、struct(結構體)、enum(枚舉)都能有協議
但是協議中有個關鍵字mutating,協議所針對類型不同,對這個關鍵字的需求也就不同
關鍵字mutating允許在實例方法中修改對象本身或屬性的值
理解:Swift中有三種type(類型):class(類),struct(結構體),enum(枚舉)
這三個類型的區別在于class是引用類型,而另外兩個是值類型。區別在于,引用類型的對象是可以動態分配的(可以變化),而值類型的對象在初始化時一般就分配好了(不準改動)。而mutating關鍵字則允許在它修飾的方法中去修改對象本身的值或對象屬性的值(self或self.xxx的值)
上述對于mutating關鍵字的原理解釋,如依然不懂就記住:
1.如果協議僅針對class,不需要mutating關鍵字
2.如果協議會被enum或struct使用,協議中的方法需要mutating修飾
例子1:對class協議
protocol ExProtocol1 {
var simpleDescription: String {
get
}
func adjust() //省略mutating關鍵字
}
class SimpleClass: ExProtocol1 {
var simpleDescription: String = "A very simple class"
var anotherProperty: Int = 110
func adjust() {
//即使不寫mutating,也可以改變方法屬性
simpleDescription += " Now 100% adjusted"
}
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription
例子2:對struct(結構體)協議,協議方法中不改變結構體屬性
protocol ExProtocol2 {
var simpleDescription: String {
get
}
func adjust() //省略mutating關鍵字
}
struct SimpleStruct: ExProtocol2 {
var simpleDescription: String = "A simple structure"
func adjust() {//不加mutating關鍵字
let testDescription = simpleDescription + "test SimpleStruct" //不改變對象屬性
print(testDescription)
}
}
var b = SimpleStruct()
b.adjust()
//b這個對象的屬性simpleDescription,值未改變
let bDescription = b.simpleDescription //A simple structure
例子3:對struct(結構體)協議,在協議方法中改變結構體屬性
protocol ExProtocol3 {
var simpleDescription: String {
get
}
//mutating在這里修飾了,結構體中的對應方法才能使用這個關鍵字修飾
mutating func adjust()
}
struct SimpleStruct2: ExProtocol3 {
var simpleDescription: String = "A simple structure"
mutating func adjust() {//使用mutating關鍵字
simpleDescription += "(adjusted)" //允許改變結構體屬性
}
}
var c = SimpleStruct2()
c.adjust()
//c這個對象的屬性simpleDescription,值發生了改變
let cDescription = c.simpleDescription
擴展
extension關鍵字代表擴展
可以使用擴展為一個現有的類型添加函數,比如新的方法和計算屬性。
extension Double {
func absoluteValue() -> Double {
return self < 0 ? -self : self
//并不是改變了self,完整代碼如下:
//let a = self < 0 ? -self : self
//return a
}
}
print((-3.2).absoluteValue())
Swift中還可以用擴展為一個類型添加協議,并實現協議屬性或方法
擴展中的協議(最好的體現mutating的例子)
protocol ExProtocol4 {
var simpleDescription: String {
get
}
mutating func adjustTest1() //mutating關鍵字
func adjustTest2() -> Int //無mutating,返回Int
}
extension Int: ExProtocol4 {
var simpleDescription: String {
return "The number \(self)"
}
mutating func adjustTest1(){ //使用mutating關鍵字
self += 42//改變了self
}
func adjustTest2() -> Int{
let total = self + 42 //使用self,但不改變
return total //返回一個臨時常量
}
func mormalFunc() -> Int { //普通方法
let zzz = self + 11 //使用方法
return zzz
}
}
//使用擴展
7.simpleDescription
//7.adjustTest1() //不允許這么寫,因為對象會發生改變
7.adjustTest2() //49,這是個臨時常量的值
/*
其實7.adjustTest1() 拆開來就是:
let servenLet = 7
servenLet.adjustTest1()
let 聲明的是個常量,adjustTest1不能改變一個常量的值。
所以不能用這個方法,把let改成var就行
*/
var serven = 7 //這里值是7
serven.adjustTest1() //使用該方法變量serven的值會發生改變
serven //這里值變成了49
serven.adjustTest2() //輸出91,但這是一個臨時常量的值
獲取協議中的值(協議實例中的值)
//一個類實現了某個協議,我們可以通過如下方法獲得協議實例
var protocolValue: ExProtocol4 = serven
//protocolValue的類型是ExProtocol4,可訪問協議中的屬性
protocolValue.simpleDescription
protocolValue.adjustTest1()//訪問協議中的方法
//protocolValue.mormalFunc() //不屬于協議的屬性或方法不能訪問
來自:http://www.cocoachina.com/swift/20161118/18131.html
本文由用戶 msconfig41 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!