開放度が高すぎるプロパティ
例えば、何かをカウントする型があったとします。increment()
メソッドでカウントアップして、count
プロパティでその値を確認できるとします。
public struct Counter {
public var count: Int = 0 // it's public!!
mutating func increment() {
count += 1
}
}
しかし、これでは、count
の値を外部の者に変更されてしまう恐れがありますし、count
プロパティ自体を private
にすると、そもそも カウントした値を外から参照できなくなってしまいます。
var counter = Counter()
counter.increment()
counter.count = 5 // oh, no!!
setter を private にして、getter を public に
そこで、setter を private
にして、getter を public
にしようとすると、こんな具合にコーディングしている人もいるかと思います。
public struct Counter {
private var _count: Int = 0 // it's private
public var count: Int {
return _count
}
mutating func increment() {
_count += 1
}
}
これで外部がカウンタの値を直接変更しようとすると……
var counter = Counter()
counter.count
counter.count = 5 // // Cannot assign to property: 'counter' is a get-only property
こんな具合に怒られてしまうので、これで、本来の意図通りにコーディングができました。めでたしめでたし。
真打登場!
と言いたいところですが、ここまで引っ張っておいて、もっと簡単な書き型があったりします。
public struct Counter {
private (set) public var count: Int = 0 // <-- !!!
public mutating func increment() {
count += 1
}
}
何と、setter のみを private
にできたりする事ができたりします。
var counter = Counter()
counter.increment()
counter.count // no compile error and should be 1
counter.count = 7 // Cannot assign to property: 'counter' is a get-only property
もちろん、public と private だけのアクセスコントロールだけの話ではありません。setter のみを fileprivate
にという事も可能ですが、残念なら、setter を public
にして、getter を private
にする事はできないようです。そして今度こそ…
Then many swift programmers enjoyed coding happily ever after....
参考資料
The Swift Programming Language Swift 3.0.1 - Access Control
【卵は世界である】setとgetには異なるアクセス修飾子を指定できる
Swift Magic: Public Getter, Private Setter
環境に関する表記
Xcode Version 8.1 (8B62)
Apple Swift version 3.0.1 (swiftlang-800.0.58.6 clang-800.0.42.1)