2017-06-11 1 views
1

これは罰金コンパイル:なぜ、will/didSetトリガイニシャライザエラーですが、通常のset/getではありませんか?

class Foo { 
    var number = 0 
    var name: String 
    init(name: String){ self.name = name } 
} 

class SubFoo: Foo { 
    init(_ x: Int){ 
     super.init(name: "abc") 

    } 

    var a: Int { 
     set {} 
     get { 
      return 0 
     } 
    } 
} 

aは、計算されたプロパティであるため、初期化を必要としません。

しかし、これはコンパイルされません:

class SubFoo: Foo { 
    init(_ x: Int){ 
     super.init(name: "abc") 

    } 

    var a: Int { 
     willSet {} 
     didSet { 
      print(oldValue) 
     } 
    } 
} 

をSubFooのinitメソッドがこれを示しています

error: property 'self.a' not initialized at super.init call super.init(name: "sdf")

aはまだ "本物" のプロパティではありませんので、コンパイラは、ここで正確に何を期待していますか?

不思議私はこれを行うことによって、エラーを消すことができます。

init(_ x: Int){ 
    a=0 
    super.init(name: "sdf") 

} 

はなぜ a=0は、通常の setwillSetために必要ではないでしょうか?

+2

'a'は、2番目の例では、計算されていない格納されたプロパティです。 'willSet'と' didSet'は単なるオブザーバーです。 – Hamish

+0

@ハミッシュそれは非常に面白いです、私はこれらのすべてのプロパティメソッドが "計算された"と思った – johnbakers

+1

私はこれが構文のデザインミスであると常に考えてきました。これらの2つは、機能の大きな違いを考えると似ています。オブザーバーが別々に宣言された場合、または少なくとも角括弧の中に入れられていない場合は、それを好むでしょう。 –

答えて

2

willSetdidSetが計算方法getsetと同様に、プロパティの後に括弧で表示されているが、彼らは、計算プロパティの動作を指しているわけではありません。 willSetおよびdidSetは、ストアドプロパティに作用します。 - 保存されたプロパティのない初期化はありませんでした

var a: Int = 6 { // this line would not compile for a computed property 
     willSet { 
     } 
     didSet { 
      print(oldValue) 
     } 
    } 

これはinitでコンパイルエラーの理由である:あなたがget/setのためにそれらのデフォルト値を提供しますが、できない理由でもあります。

関連する問題