はじめに
他の人のコード見てるときに、get setって書いてあって何やねんって思ったので、備忘録的な感じで残しておきます。
こちらのコードを見てみてください。
protocol priceAndTax {
var taxIncludedPrice: Double { get set }
}
パット見ただのプロパティの定義に見えますが、{ }
という変な記述があります。
これはコンピューテッドプロパティといって、値を自分で持たない変数のことで、プロトコルのプロパティはこれしか宣言できません。ちなみに、 var num: Int = 1
のように自分で値を持つストアドプロパティとよく比較されます。
解説
ここからは、このコンピューテッドプロパティの挙動をItemクラスにプロトコルを準拠させることで確認していきます。
class Item: priceAndTax {
var taxExcludedPrice: Double = 100
var taxIncludedPrice: Double {
get {
return taxExcludedPrice * 1.08
}
set {
self.taxExcludedPrice = newValue / 1.08
}
}
}
ItemクラスにpriceAndTaxを準拠させるとこんな感じになります。taxExcludedPrice、taxIncludedPrice
はそれぞれ税抜価格、税込価格のことです。
taxExcludedPrice
やget{ },set{ }
の中身はあとから付け足しました。
そしてこのgetの部分はゲッターといい、taxIncludedPrice
の値を取得すると呼ばれます。
対してsetの部分はセッターといい、taxIncludedPrice
に値を代入すると呼ばれます。
では、実際にゲッターとセッターを呼んで、具体的にその挙動を見ていきましょう。
let snack = Item()
snack.taxIncludedPrice = 216 // taxIncludedPriceのsetが呼ばれる
print(snack.taxExcludedPrice) // taxIncludedPriceのセッターで、新しく値がセットされてるはず
print(snack.taxIncludedPrice) // taxIncludedPriceのgetが呼ばれる
一行ずつ解説していきます。
一行目:Itemクラスでsnackインスタンスを作成しているだけです。
二行目:taxIncludedPrice
に値を代入しているので、setメソッドが呼ばれています。newValue
といういきなり出てきた変数がありますが、これはセットされる新しい値が自動的に格納される変数のことで、自分で定義する必要はありません。なのでここではnewValue
には216
が格納されています。そしてnewValue / 1.08
で216円の税抜価格、200円がtaxExcludedPrice
に格納されます。taxIncludedPrice自体には値が格納されていないということに注意してください!!!
三行目:先程200が格納されたストアドプロパティにアクセスしているので、そのまま200が出力されます。
四行目:print関数でsnack.taxIncludedPrice
でtaxIncludedPrice
の値を取得しているので、getメソッドが呼ばれます。taxExcludedPrice
には200が格納されているので、それの税込価格216
が出力されます。ここでも。taxIncludedPrice
自体の値を取得しているわけではないということに注意してください。
変数に値が格納されてないのに値が取得できるなんてちょっと不思議ですね〜
最後に
これがコンピューテッドプロパティの挙動でした。snackの値段を変更する事を考えたとき、税抜価格と税込価格両方に対してストアドを利用すると二つの変数それぞれに代入しないといけませんが、今回のようにコンピューテッドを利用すれば一行で同時に更新できるので、一方の値を更新し忘れるというミスが事前に防げそうですね。
おまけ
プロトコルに定義するコンピューテッドプロパティは、getが必須でsetは任意らしいです。なのでこう書いても大丈夫です。
protocol priceAndTax {
var taxIncludedPrice: Double { get }
}
そうするとtaxIncludedPrice
はこう記述できます。
var taxIncludedPrice: Double {
get {
return taxExcludedPrice * 1.08
}
}
さらにgetのみの定義だと、getを省略して記述することも可能です。
var taxIncludedPrice: Double {
return taxExcludedPrice * 1.08
}
さらにさらに一行で値の返却のみをする場合、関数と同じく暗黙のreturnが利用可能なので、
var taxIncludedPrice: Double {
taxExcludedPrice * 1.08
}
こんなに短くなりました
参考文献