【Swift】プロパティのsetとgetには異なるアクセス修飾子を指定できる
記事内に広告を含む場合があります。記事内で紹介する商品を購入することで、当サイトに売り上げの一部が還元されることがあります。

Swiftでは、プロパティのセッタ(set節)とゲッタ(get節)に異なるアクセス修飾子を指定することができます。
以下、実例を見ていきましょう。
プロパティに対する通常のアクセス指定
まずは、プロパティに対する通常のアクセス指定方法を見ていきましょう。
public struct MyData {
// get/set共に、同じソースファイルからアクセス可能
private var privateData : String = ""
// get/set共に、同じモジュールからアクセス可能
internal var internalData : String = ""
// get/set共に、どこからでもアクセス可能
public var publicData : String = ""
public init() {
}
}
MyDataを異なるモジュールから使ってみましょう。
var data1 = MyData() // error: value of type 'MyData' has no member 'privateData' data1.privateData = "private" // error: value of type 'MyData' has no member 'internalData' data1.internalData = "internal" data1.publicData = "public"
異なるモジュールから「private」「internal」に指定したプロパティへアクセスしたので、「value of type ‘型名’ has no member ‘プロパティ名’」というエラーが出ます。
取得をpublic、設定をprivateにするには?
さて、取得をpublic、設定をprivateにするにはどうしたらいいでしょう?
最初に考えたのは以下のような方法です。
public struct Person {
// getもsetもpublic
public var name : String
private var age : Int
// publicなgetterを用意する
public func getAge() -> Int {
return age
}
public init(name:String, age:Int) {
self.name = name
self.age = age
}
}
プロパティ自体はprivateにしておいて、取得できるメソッドをpublicに指定するわけです。
これで要件は満たせますが、ちょっと面倒くさいですよね・・・。
セッタに対し、ゲッタよりも低い可視性を与える
実はSwiftでは、setとgetに異なるアクセス修飾子を指定できます。
セッタに対してだけ設定をするため、public、internal、privateに加えて、public(set)、internal(set)、private(set)という修飾語が用意されています。
引用元 : 詳解 Swift 改訂版
以下がその実例です。
public struct Person {
// getもsetもpublic
public var name : String
// getはpublic、setはprivate
public private(set) var age : Int
public init(name:String, age:Int) {
self.name = name
self.age = age
}
}
先ほどの例に比べて楽でいいですね!では、異なるモジュールでPersonを使ってみましょう。
var p1 = Person(name: "sato", age: 30) print(p1.name) p1.name = "suzuki" print(p1.age) // error: cannot assign to property: 'age' setter is inaccessible p1.age = 20
nameに関してはgetもsetも行えていますね。しかしageに関してはsetのみ「cannot assign to property: ‘age’ setter is inaccessible」というエラーになっています。
格納型プロパティだけでなく、計算型プロパティに対しても指定を行えます。
public struct Person {
public var name : String
private var _age : Int
public private(set) var age : Int {
get {
return self._age
}
set {
self._age = newValue
}
}
public init(name:String, age:Int) {
self.name = name
self._age = age
}
}
注意点として、getに対して、setよりも低い可視性を与えることはできません。
そのような指定を行ってしまうと、以下のように「Private property cannot have a public setter」のようなエラーが出てしまいます。
public struct Person {
// getもsetもpublic
public var name : String
// error: Private property cannot have a public setter
private public(set) var age : Int
public init(name:String, age:Int) {
self.name = name
self.age = age
}
}
@akio0911はこう思った。
わざわざpublicな取得メソッドを作ったりしなくても良いので、これは嬉しい言語仕様ですね。
今回紹介した言語仕様も含めて、Swiftのアクセスコントロースに関する仕様は以下の本が詳しいです。
関連記事
この記事が気に入ったら「いいね!」しよう
Twitterで更新情報をゲット!





