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

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

記事内に広告を含む場合があります。記事内で紹介する商品を購入することで、当サイトに売り上げの一部が還元されることがあります。

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

この記事を書いた人
あきお(@akio0911
派手髪iOSエンジニア。Twitterアカウントは@akio0911。YouTubeチャンネル「あきおチャンネル」にてiOSアプリ開発講座を公開中。著書に「iPhoneアプリ開発レシピ」「cocos2d for iPhoneレッスンノート」など。iOSアプリ開発をテーマとしたオンラインサロン「アプリ道場サロン」を運営。東京・大阪にてアプリ開発講座「アプリクリエイター道場」を主催。

関連記事

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

Twitterで更新情報をゲット!

PAGE TOP ↑