LoginSignup
0
1

【Swift】プロトコルのプロパティ宣言時に記述する{ get }と{ get set }の意味とその違い

Posted at

📚 参考

🔰 { get }{ get set }の意味とその違い

プロパティ要件(Property Requirements)に記述する{ get }{ get set }は、プロトコル型インスタンスに対するパーミッションであり、Computed Propertyの宣言時に記述するget {...}set {...}とは無関係である

プロトコル型とは
protocol Animal {}
struct Dog: Animal {}

// ✅ プロトコル型インスタンス
let animal: Animal = Dog()
// ❎ プロトコル型インスタンスでない
let dog: Dog = Dog()
プロトコルの宣言
protocol Sample {
  /**
    { get } .. プロトコル型インスタンスの場合は代入不可
    { get set } .. プロトコル型インスタンスの場合でも代入可能
   */
  var get_constant: Int { get }
  var get_variable: Int { get }
  var get_computed: Int { get }
  var get_private_set: Int { get }
  var getset_variable: Int { get set }
  var getset_computed: Int { get set }
}
プロトコルへの準拠(プロパティ要件)
struct SampleStructure: Sample {
  let get_constant: Int
  var get_variable: Int    // ✅ storedでもcomputedでもよい
  var get_computed: Int {  // ✅ storedでもcomputedでもよい
    get {
      return secret
    }
    set {  // ✅ プロパティ要件の{ get }とComputed Propertyの{ get set }は無関係
      print("private variable 'secret' value has changed.")
      secret = newValue
    }
  }
  private(set) var get_private_set: Int
  var getset_variable: Int
  var getset_computed: Int {
    get {
      return secret
    }
    set {
      print("private variable 'secret' value has changed.")
      self.secret = newValue
    }
  }

  // 説明用のPrivateプロパティ
  private var secret: Int = -1
}

Swiftは、基本的にプロトコル型は自身のプロトコルに準拠していない(= self-conformanceをもたない)ものとする。

そうでないと、後述するParametric Polymorphismにおいてはプロトコルのメンバが未定義動作を引き起こしてしまう。

Parametric Polymorphismによる未定義動作
func protocolTypeDoesNotConformProtocol<S: Sample>(_ sample: S) {
  let num: Int = sample.get_constant  //  ⚠ sampleがSampleインスタンスの場合は未初期化のため、未定義動作になる
}
プロパティへの値の代入
struct SampleStructure: Sample {
  init() {
    get_constant = 0
    get_variable = 0
    get_computed = 0
    get_private_set = 0
    getset_variable = 0
    getset_computed = 0
  }

  mutating func mutate() {
    // get_constant = 1  ⛔ cannot assign to property: 'get_constant' is a 'let' constant
    get_variable = 1
    get_computed = 1
    get_private_set = 1
    getset_variable = 1
    getset_computed = 1
  }
}

// ✅ プロトコルに準拠したインスタンスからは{get}要件のプロパティに対して代入可能
var conformed: SampleStructure = SampleStructure()
// conformed.get_constant = 1  ⛔ cannot assign to property: 'get_constant' is a 'let' constant
conformed.get_variable = 1
conformed.get_computed = 1
// conformed.get_private_set = 1  ⛔ cannot assign to property: 'get_private_set' setter is inaccessible
conformed.getset_variable = 1
conformed.getset_computed = 1

// ❎ プロトコル型インスタンスからは{get}要件のプロパティに対して代入不可
var unconformed: Sample = SampleStructure()
// unconformed.get_constant = 1  ⛔ cannot assign to property: 'get_constant' is a get-only property
// unconformed.get_variable = 1  ⛔ cannot assign to property: 'get_variable' is a get-only property
// unconformed.get_computed = 1  ⛔ cannot assign to property: 'get_computed' is a get-only property
// unconformed.get_private_set = 1  ⛔ cannot assign to property: 'get_private_set' is a get-only property
unconformed.getset_variable = 1
unconformed.getset_computed = 1
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1