2017-07-12 5 views
0

:カスタム初期化子は、それらが初期化タイプ以下のアクセスレベルを割り当てることができるアクセスレベル3.1引用</em><em>スウィフトプログラミング言語(スイフト3.1)から

。唯一の例外は、必要なイニシャライザ(Required Initializersで定義)です。必要なイニシャライザは、それが属するクラスと同じアクセスレベルでなければなりません。

もしそうなら、なぜこのコードはコンパイルされて動作しますか?スイフトで

private class GoofyClass { 
    public init(mood: String) {} 
    public required init(isCrazy: Bool) {} 
} 

private let shock = GoofyClass(mood: "shocked") 
private let crazy = GoofyClass(isCrazy: true) 
+0

なぜでしょうか?スーパークラスはありません、そうですか? 'public'と宣言されている間は、' init(isCrazy:) 'と' init(mood:) 'の2つがあります。私があなたが問題を抱えているのが見えるのは、あなたが何も言わなかったことだけです。私はinitsが 'public'で、classは' private'です。はい、私はそれが(Xcode 8.3コンパイラのバグかもしれません)ビルドには驚いていますが、私はあなたが簡単に 'プライベート'クラスを初期化しようとするあなたのアプリケーションをクラッシュするとは思わない。 – dfd

+0

ここで唯一のことは 'private'クラスと' public'初期化子です。だから私はその本から引用文を投稿した。 :) –

+0

さらに調査した結果、プロトコルのアクセスレベルの動作が本書に記載されているものと異なることがわかりました。それはバグのコンパイラかもしれません。 –

答えて

2

は、クラス/構造体自体よりも制限アクセスレベルを持つクラスまたは構造体のメンバーは自動的にクラス/構造体と同じレベルにダウングレードされています。私はこれが言語設計者の意図的な設計決定であると信じています。あなたのケースでは

は、(すなわち、それは別の型の中にネストされていない)クラスはファイルのトップレベルで宣言されたと仮定すると、あなたがpublicを宣言したinit sが、実際には、fileprivateあります。

唯一の例外は、必須イニシャライザ(必須イニシャライザで定義)です。必要なイニシャライザは、それが属するクラスと同じアクセスレベルでなければなりません。

この

では、例えばそのクラスよりも必要な初期化子 より制限のアクセスレベルを作ることができないという事実に言及しています

open class Foo 
{ 
    internal required init() // error 
} 
+0

明示的な宣言には当てはまりません。 –

+0

@RoboRobokまあ、 'fileprivate'クラスでpublic初期化子を定義するのはエラーではありません。 – JeremyP

+0

しかし、公式の本によると、それはすべきです。より低いアクセスレベルのエンティティの内部でより高いアクセスレベルを持つものを定義するのと同じようにエラーが発生します。 –

関連する問題