【Swift】privateなタイプメソッド作るなら、privateな関数でも良いかもと思った

公開日: : 最終更新日:2016/02/10 iPhoneアプリ開発

20160208-152320.jpg

structとかclassの中で、ちょっとした処理を担当させるprivateなタイプメソッドを作ることがよくあるんですけど、これはSwiftならprivateな関数でもいいんじゃないか?とふと思いました。

(より良い方法などがあれば、ぜひakio(@akio0911)宛にお知らせ下さい)

    

privateなタイプメソッドの例

まず、privateなタイプメソッドの例を挙げましょう。

public struct VeryVeryLongNameStruct1 {
    private var a : Int
    private var b : Int
    
    // getterはpublic、setterはprivate
    public private(set) var sum : Int
    
    public init(a:Int, b:Int) {
        self.a = a
        self.b = b
        self.sum = VeryVeryLongNameStruct1.calcSum(a: a, b: b)
    }
    
    private static func calcSum(a a:Int, b:Int) -> Int {
        return a + b
    }
}

以下が使用例。

let data1 = VeryVeryLongNameStruct1(a: 10, b: 20)
print(data1.sum)

これはこれでいいんですけど、タイプメソッドを使う時に

self.sum = VeryVeryLongNameStruct1.calcSum(a: a, b: b)

とわざわざ型名を入れなきゃいけないのが面倒くさいなーと感じます。

型名が長かったり、タイプメソッドを呼び出す箇所が多かったりするとちょっとしんどいです。

    

(補足)タイプメソッド内であればselfを使って他のタイプメソッドを呼び出せる

ちなみに補足ですが、タイプメソッド内であればselfを使って他のタイプメソッドを呼び出せます。

以下、その実例です。

public struct VeryVeryLongNameStruct3 {
    private var a : Int
    private var b : Int

    // getterはpublic、setterはprivate
    public private(set) var sum : Int

    // getterはpublic、setterはprivate
    public private(set) var mul : Int
    
    public init(a:Int, b:Int) {
        self.a = a
        self.b = b
        (self.sum, self.mul) = VeryVeryLongNameStruct3.calcResult(a: a, b: b)
    }
    
    private static func calcSum(a a:Int, b:Int) -> Int {
        return a + b
    }
    
    private static func calcMul(a a:Int, b:Int) -> Int {
        return a * b
    }
    
    private static func calcResult(a a:Int, b:Int) -> (Int, Int) {
        // タイプメソッド内であれば、selfを使って他のタイプメソッドを呼び出せる
        return (
            self.calcSum(a: a, b: b),
            self.calcMul(a: a, b: b)
        )
    }
}

これは楽ちん!タイプメソッド外でもselfを使ってタイプメソッドを呼び出せればいいんですけどねえ。現状のSwiftではできないみたいです。

    

外からアクセスさせたくないならprivateな関数でも良いのでは?

そこでふと気付きました。「外からアクセスさせたくないんだったら、privateなタイプメソッドじゃなくて、privateな関数でもいいんじゃないの?」

そこで書いてみたのが以下のようなコードです。

private func calcSum(a a:Int, b:Int) -> Int {
    return a + b
}

public struct VeryVeryLongNameStruct2 {
    private var a : Int
    private var b : Int

    // getterはpublic、setterはprivate
    public private(set) var sum : Int
    
    public init(a:Int, b:Int) {
        self.a = a
        self.b = b
        self.sum = calcSum(a: a, b: b)
    }
}

Swiftにおけるprivateは

private
定義されたソースファイルの中だけで利用できます。他のソースファイルからはアクセスできません。

引用元 : 詳解 Swift 改訂版

という意味なので、型と同じソースファイル内にprivateな関数を作れば、「クラスからはアクセスできるけど、外からアクセス出来ない、privateなタイプメソッド的な処理を作りたい」という要件を満たせますね。

そしてなにより、呼び出す際には

self.sum = calcSum(a: a, b: b)

という風に、型名を付けなくても良いので楽です。

    

@akio0911はこう思った。

メソッドではない普通の関数も、いろいろと使いドコロがありそうだと感じました。

そしてSwiftのアクセス制御がソースファイル&モジュール単位であることの良さが少しずつ感じられるようになってきました。

最初は「え?なんでクラス単位じゃないの?」って思ったりもしましたが・・・。

    

Swiftのタイプメソッド・アクセス制御などに関する文法・仕様は、以下の本が詳しく載っています!

関連記事

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

follow us in feedly

Feedlyで最新記事を購読

Twitterで更新情報をゲット!

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

PAGE TOP ↑