2017-09-08 12 views
0
struct Circle { 
    // Properties 

    var radius: Double { 
     didSet { 
      if oldValue < 0 { 
       radius = 0 
      } 
     } 
    } 
    var area:Double { 
     get{ 
      return Double.pi * pow(radius, 2) 
     } 
    } 
    var circumference: Double { 
     get { 
      return 2 * radius * Double.pi 
     } 
    } 
    init() { 
     radius = 0 
    } 
    init(radius r: Double) { 
     radius = r 
    } 

} 

// test circle 

var testCircle = Circle() 
print ("radius:", testCircle.radius, "area: ", testCircle.area, "circumference: ", testCircle.circumference) 

var testCircle2 = Circle(radius: 2.5) 
print("radius: ", testCircle2.radius, " area: ", testCircle2.area, "circumference: ", testCircle2.circumference) 

var testCircle3 = Circle(radius: 20) 
print("radius: ", testCircle3.radius, "area: ", testCircle3.area, "circumference: ", testCircle3.circumference) 

var testCircle4 = Circle(radius: -4.5) 
print("radius: ", testCircle4.radius, "area: ", testCircle4.area, "circumference: ", testCircle4.circumference) 
+0

半径値が0より小さい円を作成しようとするのが目的です。これは新しいです! – Tom

+1

この小切手の目的は何ですか?ユーザーが負の値を設定するのを禁止し、その場合は0に設定しますか?これが当てはまる場合は、 'oldValue'ではなく' radius'の現在の値をチェックする必要があります。後者は、*あなたが変更を行う*前の値が何であったかをチェックします。 –

+1

いくつかの管理ポイント:1.コードが適切にフォーマットされていることを確認します。質問の内容の中にあなたの質問があるかどうかを説明する必要があります。タイトルやコメントにはありません – toddg

答えて

1

実際にプロパティが変更された後にdidSetが呼び出されます。 oldValueには前の値が入ります。

新しい値が負であるかどうかを確認する必要があります。

更新コードに:あなたはradius(最新値)が負であるかどうかを確認したい

var radius: Double { 
    didSet { 
     if radius < 0 { 
      radius = 0 
     } 
    } 
} 

didSetwillSetは、初期化中に呼び出されていないため

init(radius r: Double) { 
    radius = r >= 0 ? r : 0 
} 

これは、次のとおりです。

はまた、あなたのinit方法を更新する必要があります。したがって、initメソッドはパラメータを検証する必要があります。さらに以下のようにあなたのradiuscircumferenceプロパティを簡素化することができますサイドノートとして

var area:Double { 
    return Double.pi * pow(radius, 2) 
} 

Aは、読み取り専用のコンピュータのプロパティはget { }を必要としません。

2

didSetinitの間はプロパティオブザーバが呼び出されません。割り当てをdefer { ... }ステートメントにラップして、didSetを強制的に呼び出すことができます。例えば

:デフォルトの半径は0になりたい場合は

init(radius r: Double) { 
    defer { radius = r } 
} 

、私はそうのようなradiusのデフォルトパラメータ値を使用してお勧めします:

init(radius r: Double = 0) { 
    defer { radius = r } 
} 

...あなたは2つのinitメソッドを避け、Circle()radius = 0)とCircle(radius: 3)radius = 3)としてまだCircleを初期化します。

+0

ですFYI - この答えはOPの質問ではなかった 'someCircle.r = -4.5' – rmaddy

+0

@rmaddyのようなコードの問題を修正するために何もしません。 –

+0

確かです。質問のタイトルを読んでください。 'didSet'は正しく書かれていません。いくつかの状況下で 'didSet'が呼び出されていないという事実は解決されるだけの追加の問題です。 – rmaddy

関連する問題