おはようございます。バットマンです。PlayStation VR でバットマン:アーカム VRを遊んだところ、現実とゲームの区別がつかなくなりました。ヘッドセットを外した後も、手がオブジェクトにめり込むんじゃないかと錯覚するようになった。
ところで Swift ピープルの皆さんも、最近はプロジェクトを Swift 3 にマイグレーションしたりして暮らしていらっしゃることかと思います。御多分に洩れず、僕もマイグレーションして暮らしています。いろいろコツも掴めてきたところではありますが、それはともかく、private と fileprivate について割り切れないものを感じている昨今です。
private と fileprivate
SE-0025 Scoped Access Level で Swift 3 に導入された private と fileprivate は、Swift 2 までの private はファイル内で可視であるというのを fileprivate とした上で、定義内で可視であるという private を新たに導入したものである。これによって private の意味が他の言語などと揃い、一方で Swift の extension の仕組みと親和的な fileprivate が残された、ということになる。
Swift 2 から Swift 3 へ自動マイグレータを適用すると、Swift 2 の private はすべて Swift 3 の fileprivate へ書き換えられる。これらは全く同じなので正しい。しかし fileprivate は長ったらしいので、可能なら private へ置き換えていきたい。ひとまずすべて private にしてみて、コンパイルが通るように fileprivate へ戻す、といった方法で可能な限り private にしていく。extension で何らかの protocol に準拠していて、そのために stored property を fileprivate にしなければならない、というようなことがある。
そういうことをしていると、いまこの private と fileprivate の差が、いったい何の意味を持っているのかだんだん分からなくなる。このコードを読むとき、private と fileprivate の違いをどういう風に解釈したらよいのか。
同一ファイル上で extension によって実装を分けている場合、private と fileprivate を明確に分離できない。同一ファイル上の別な class や struct であれば、private と fileprivate の違いが役に立つかもしれない。しかしそれは、そもそも別なファイルに分けておけばよかったのかもしれない。
ということで、private と fileprivate の分離自体は正しいのだけど、実際にはうまく使い分けることが難しく、一筋縄にはいかない。
他方で internal や public、open は明々白々に使い分けられて便利。