【Swift】プロパティのsetとgetには異なるアクセス修飾子を指定できる

公開日: : 最終更新日:2017/03/31 iPhoneアプリ開発

20160209-123839.jpg

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のアクセスコントロースに関する仕様は以下の本が詳しいです。

この記事が気に入ったら「いいね!」しよう

follow us in feedly

Feedlyで最新記事を購読

Twitterで更新情報をゲット!

LINEでご感想・ご要望お送りください!
(スマホでLINEを起動 > 友だち追加 > QRコード)

関連記事

I20151202-232710.jpg

【Swift 2】配列(Array)を初期化する方法

Swiftで配列(Array)を初期化する方法についてまとめてみたいと思います!   

記事を読む

20141228-232009.jpg

【Swift】as?演算子を使ったキャストでは結果がoptionalとなる

今日はSwiftのas演算子とas?演算子について解説したいと思います。as演算子について

記事を読む

20160309-131202.jpg

ゆるい入門書では物足りない人向けの濃い内容!「本気ではじめるiPhoneアプリ作り」

ヤフー株式会社のiOSエンジニアである西 磨翁(にし まお)さんより、「本気ではじめるiPhon

記事を読む

20160730-172416.jpg

Auto Layoutで非表示にした部分を詰める(トルツメ)する方法

Auto Layoutを使って非表示にしたコントロールの部分を詰める(トルツメ)方法を説明します

記事を読む

20160802-232454.jpg

【Xcode 7】メソッドがどこから呼びだされているかを調べる方法

Xcode 7で、メソッドがどこから呼び出されているのか調べる方法を紹介します!     方法

記事を読む

20141210-164612.jpg

【Swift】Generated Header内にSwiftクラスの定義が記述されない場合の確認事項【Xcode6】

Swiftで書いたクラスをObjective-Cで使う際には、「Generated Header

記事を読む

20141006-103526.jpg

Xcode 6におけるNSUserDefaultsのplistの在り処と、内容を確認・書き換え・削除する方法

Xcode 6にて、NSUserDefaultsのplistファイルの在り処と、内容を確認・書き

記事を読む

I20160207-111059.jpg

【Swift】Xcodeで型推論された変数や定数の型を調べる方法

Swiftには、そのデータ型が明らかであれば型を明記する必要が無い「型推論」という機能があります

記事を読む

20160508-170745.jpg

SwiftTaskで失敗したタスクによって異なるエラー処理を行う方法

SwiftTaskで複数のタスクを.successでチェーンさせ、失敗したタスクによって

記事を読む

I20160119-155700.jpg

Xcodeで80文字目のところにガイドラインを表示する方法

Xcodeで80文字目のところに線(ガイドライン)を表示する方法について解説します! 「ソース

記事を読む

I20170521-225453.jpg
東京駅八重洲口の「羊肉酒場 悟大」で網焼きジンギスカンを頂きました!

ゆうせいさんと株式会社 大庄さんからご招待頂き、悟大withサッポ

I20170514-165235.jpg
iPhoneと連携できる体重体組成計「Withings Body Cardio」を使ってます

ジムに通い始めて体脂肪率が落ち始めたのをキッカケに、iPhoneと

I20170507-155440.jpg
【派手髪】ハーレイクイン風の髪色に染めてもらいました

2016年10月20日、ハーレイクイン風の髪色に染めてもらいました

I20170504-173110.jpg
【メンズネイル】東京・新宿のネイルサロンでターコイズのホログラムネイルしてもらった

ネイルネタが1年分くらい溜まっているので、ちょっとずつ書いていこう

I20170502-010117.jpg
SNUGGのライトニングケーブルが耐久性高し。8ヶ月使ってますが断線の気配なし!

iPhoneの充電&転送ケーブルであるLightningケーブルっ

→もっと見る

PAGE TOP ↑