變量如果用let 聲明為協(xié)議,修改它的屬性會報錯弱恒。
例子如下:MyProtocol 是一個協(xié)議询刹,MyClass2是一個類
let p0 : MyProtocol = MyClass2() //這樣寫會編譯失敗
p0.name = "000"
但是,同樣的
變量如果用let 聲明為class左冬,修改它的屬性卻不會報錯桐筏。
完整代碼
protocol MyProtocol {
var name : String {get set}
}
class MyClass2 : MyProtocol {
var name : String = "..."
}
func _case0() {
var p0 : MyProtocol = MyClass2()
//let p0 : MyProtocol = MyClass2() //這樣寫會編譯失敗
p0.name = "000"
let p1 : MyClass2 = MyClass2()
p1.name = "111"
}
所以for in 處理協(xié)議數(shù)組的時候,如果要修改元素的屬性拇砰,也要在for后面增加var
for var item in MyProtocolArray
記住這個規(guī)則好像還不夠....總想要解釋個為什么
所以梅忌,來吧,這里嘗試解釋一波
把之前的協(xié)議用struct實現(xiàn)一遍除破,非常輕松簡單
struct MyStruct2 : MyProtocol {
var name : String = "..."
}
嘗試對let聲明的結(jié)構(gòu)體屬性進行修改的話牧氮,會看到跟協(xié)議一樣的報錯,表現(xiàn)一樣的特性
var p2 : MyStruct2 = MyStruct2()
//let p2 : MyStruct2 = MyStruct2() //這樣寫會編譯失敗
p2.name = "222"
結(jié)論就是
用let聲明的protocol或struct變量瑰枫,都不可以修改其屬性踱葛。除非改為var來聲明
換個更好理解的方式來闡述結(jié)論
1.let聲明的class可以修改其屬性,而let聲明的struct卻不可以
2.protocol背后到底是class還是struct,上下文無法推測光坝。所以swift只能讓protocol表示的變量表現(xiàn)出最保守的struct的特征尸诽,不可以隨意修改其屬性。
把一個let聲明的class變量賦值了另一個實例(這就不是在屬性層級的修改)盯另,結(jié)論肯定是不允許的
其實這里針對第一點性含,可以留一個問題
為什么同樣作為constant,class可以修改其屬性鸳惯,而struct不可以商蕴?
let x : classA = objA叠萍,是讓x指向objA的地址,constant的范疇就是x的這個地址不可以修改绪商。而objA.name等屬性并不在let限定里苛谷。
let y : structA = valA , 是讓 y指向valA這個完整的數(shù)據(jù)區(qū)域,而valA.name是這個數(shù)據(jù)區(qū)域的一部分格郁,自然也是全體都受到了let的限定腹殿。
推論到protocol數(shù)組上
對于這樣的數(shù)組let arr : [MyProtocol], arr[0].name = “123”是不合法的。因為arr[0]是個protocol理张,它應該表現(xiàn)為保守的struct特性赫蛇,所以連同其屬性name一并都是let范疇不可以修改。
as! 為class即可修改name屬性雾叭。
上圖說話