為什麼 { get } 可以 assign?!


這篇是關於 { get }{ get set } 的基礎筆記。

問題點

最近發現為什麼被定義成 { get } 的屬性為什麼還可以被 assign 值覺得不可思議,因此再次幫自己舉例釐清到底為什麼。

而這個原因(可以被 assign)雖然看起來理所當然,但是在實踐 pop 的時候可能因為覺得太過理所當然會不小心忽略,或是在指定成 protocol 型別之前就先被拿來當成繞過 protocol 限制的方法,姑且不論好壞,就先決定記下來。

像是以這樣的定義

protocol A: class {
    var a: String! { get }
}

class AClass: A {
    var a: String!
    init() {}
}

發現可以被 assign 值的實作是這樣:

let a1 = AClass()
a1.a = "some text"

這樣 Xcode 的編輯器不會抱怨, runtime 也一樣照樣過。
原因就是在 a1 雖然用了有 A 成分的 AClass ,但是對編譯器來說他還是 AClass ,protocol A 的優先度反而不是更高的。

不過如果這樣寫,明確的指定我的變數就是 protocol A

let a2: A = AClass()
a2.a = "some text"

Xcode 就會如期待的抱怨了:

環境

Xcode 11.3.1, Playground

參考