簡體   English   中英

為什么我不能在 Swift 中使用 let in 協議?

[英]Why I can't use let in protocol in Swift?

我對 Swift 中關於var關鍵字 {get set}的使用的協議有疑問。

來自Apple 文檔

如果協議要求屬性是可獲取和可設置的,則該屬性要求不能通過常量存儲屬性或只讀計算屬性來滿足。 如果協議只要求一個屬性是可獲取的,那么任何類型的屬性都可以滿足該要求,並且如果這對您自己的代碼有用,那么屬性也是可設置的也是有效的。

屬性要求總是聲明為變量屬性,並以 var 關鍵字為前綴。 可獲取和可設置屬性通過在類型聲明后寫入 { get set } 來表示,而可獲取屬性通過寫入 { get } 來表示。

我不明白為什么我不能使用let 只有get的協議中的var不只是let嗎?

像這樣:

protocol someProtocol 
{
   var someProperty: String { get }
}

它不僅僅是:

protocol someProtocol 
{
   let someProperty: String
}

我錯過了什么?

“只有 get 的協議中的 var 不只是 let 嗎?” 不。 let表示一個常量。 但這里不是這種情況。 考慮以下:

protocol SomeProtocol {
    var someProperty: String { get }
}

class SomeClass : SomeProtocol {

    var someProperty: String = ""

    func cla () {
        someProperty = "asd"
    }
}

let someInstance = SomeClass()

print(someInstance.someProperty) // outputs ""
someInstance.cla()
print(someInstance.someProperty) // outputs "asd"

該協議指定了符合類向外部顯示的內容 - 一些名為somePropertyString類型的屬性,您至少可以獲得。

如果協議指定{ get }您的類可以通過let someProperty: String = ""選擇符合,但它也可以類似地通過上述代碼選擇符合。 另一方面,如果協議指定了{ get set } ,則您不能在實現中使用let ,但也必須使其可設置。

協議不能簡單地定義一個值必須是常量——也不應該,這是一個實現細節,必須由實現它的類/結構來處理(或決定)。

區別在於

protocol MyProtocol {
    let someProperty: String
}

這是沒有意義的——協議不應該規定someProperty如何定義/存儲的,只是作為一個屬性可用。 它可以是計算的或存儲的屬性,但這是由實現者決定的,而不是協議本身。

protocol MyProtocol {
    var someProperty: String { get }  // abstract interface
}

struct MyStruct: MyProtocol {
    let someProperty: String  // concrete implementation: stored property
}

struct OtherStruct: MyProtocol {
    let i: Int
    var someProperty: String { return "\(i)" }  // concrete implementation: computed property
}

這是完全允許的!

我認為一個協議可以要求一個結構有一些東西,但它不能限制結構或對象的功能。 這不應該阻止您做您可能想在代碼中做的事情,例如,在協議中使用var並在實現中使用let是可以接受的。

protocol MyProtocol {
    var trythis: Int { get }
}

struct MyStructure: MyProtocol {
    let trythis: Int
}

let聲明的屬性在后台被認為是read-only 出於這個原因,協議可以通過將屬性設置為只讀來要求屬性是常量。 可以使用一些Objc運行時函數property_getAttributes來驗證此推論。

protocol SomeProtocol {
    var someTypeProperty: Int { get }
}

struct Foo: SomeProtocol {
    let someTypeProperty: Int
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM