web-dev-qa-db-ja.com

Swiftのプロトコルでletを使用できないのはなぜですか?

Swift(varkeywords {get set}

Appleドキュメント から:

プロトコルがプロパティを取得および設定可能にする必要がある場合、そのプロパティ要件は、保存された定数プロパティまたは読み取り専用の計算プロパティでは満たすことができません。プロトコルが取得可能なプロパティのみを必要とする場合、要件はあらゆる種類のプロパティで満たすことができ、これが独自のコードに役立つ場合、プロパティも設定可能であることが有効です。

プロパティの要件は常に変数プロパティとして宣言され、varキーワードがプレフィックスとして付きます。 gettableおよびsettableプロパティは、型宣言の後に{get set}を記述することで示され、gettableプロパティは{get}を記述することで示されます。

letを使用できない理由がわかりません。 getのみのプロトコルのvarは、単なるlet

このようなもの:

protocol someProtocol 
{
   var someProperty: String { get }
}

それだけではありません:

protocol someProtocol 
{
   let someProperty: String
}

私は何かが欠けていますか?

59

"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"

プロトコルは、適合クラスが外部に表示するものを指定します-Stringという名前のsomePropertyという名前のプロパティは、少なくとも getになります。

プロトコルで{ get }が指定されている場合、クラスはlet someProperty: String = ""を使用して準拠することを選択できますが、上記のコードを使用して準拠することも選択できます。一方、プロトコルで{ get set }が指定されている場合、実装でletを使用することはできませんが、同様に設定可能にする必要があります。

プロトコルは、値が一定でなければならないことを単純に定義することはできません。また、値を実装するクラス/構造体が注意する(または決定する)必要がある実装の詳細でもありません。

54
luk2302

違いは

protocol MyProtocol {
    let someProperty: String
}

これは意味がありません—プロトコルが指示することは想定されていませんhowsomePropertyが定義/保存されます。thatのみがプロパティとして利用可能です。計算されたプロパティまたは保存されたプロパティのいずれかですが、プロトコル自体ではなく、実装者が決定する必要があります。

そして

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
}

これは完全に許可されています!

36
jtbandes