hiragram no blog

iOSとか

Swift3の新しいアクセス修飾子について考察

3行で

  • Swift3から新たなアクセス修飾子 open,fileprivateが追加された
  • privateの扱いが変わった
  • ゆるい順に、open,public,internal,fileprivate,private

open

「モジュール外からアクセスでき、 サブクラス化(継承)可能である」ことを示すアクセス修飾子。以前まではpublicがこれを示していたが、publicは「モジュール外からアクセスできるが、 サブクラス化(継承)は出来ない」に変更された。

openはSwift2以前のpublicにあたり、Swift3のpublicはSwift2以前のpublicfinal修飾を付け足したもの?

fileprivate

「同じファイル内からのみアクセス可能である」ことを示すアクセス修飾子。Swift2以前のprivateと同じ。Swift3のprivateは、「定義されたスコープ内からのみアクセス可能」に変更された。

利用

openpublic、及びfileprivateprivateの使い方、使い分けについて考察する。

まず、Xcode8でできるSwift3のシンタックスへのコンバートをかけると、

  • publicはそのまま
  • privatefileprivate

になった。

近年Appleプロトコル指向プログラミング(Protocol Oriented Programming, POP)を推進しており

  • 参照型のクラスよりも値型の構造体を使いましょう(構造体は継承が無い)
  • 継承を使わずにプロトコルとエクステンションで実現しましょう

と考えているようで、コンバート時にpublicopenに置換されないのは「なるべく継承させないように作ろうね」というメッセージなのではと感じた。

privatefileprivateの使い分けについてはまだ考察中で、基本的にはprivateに寄せて参照できるスコープを狭くするべきだと思うが、一方でSwiftには

struct Human {
  var name: String
}

extension Human: HogeProtocol {
  func hogeMethod() {
    print("hoge")
  }
}

extension Human: FugaProtocol {
  func fugaMethod() {
    print(name)
  }
}

可読性の向上のためにプロトコルの実装をエクステンションとして切り出して書く派も存在し、もしプロパティnameprivateだった場合には2つのエクステンションからは参照できなくなる。

安全のためにスコープを狭くするべきか、可読性のために多少スコープの広がりを許容するかの問題だが、これはどちらを取るべきなんだろうか。

まとめ

基本的に自作の型でopenをたくさん使うとしたらライブラリ作者くらいであろう。Appleが継承地獄から脱却しようとしているのは明らかなので、それに沿う形で順応していこうと思う。

fileprivateについては、世間がどう受け止めるかという感じがするので、もうすこし様子を見たい。

参考