
Swiftでアプリを作っていると、「コンピューテッドプロパティ」という言葉を見かけることがある。
「なんだか難しそう…」と思うかもしれないが、使い方を知ってしまえばとても便利な仕組みである。
この記事では「コンピューテッドプロパティって何?」というところから、「どんな時に使えばいいの?」というところまで、なるべく専門用語を使わずに紹介する。
Contents
コンピューテッドプロパティってなに?
コンピューテッドプロパティとは、計算して値を出すプロパティのことだ。
普通の変数やプロパティは中に値を「持っている」が、コンピューテッドプロパティはその場で「計算して出す」だけで、中に値を持っていない。
下記はコンピューテッドプロパティの簡単な例だ。
1 2 3 4 5 6 7 8 | struct Rectangle { var width: Double var height: Double var area: Double { return width * height } } |
このarea
(面積)は、「幅(width) × 高さ(height)」の値を受け取り、計算して毎回結果を返している。
area
の中に値が入っているわけではない。
これがコンピューテッドプロパティだ。
コンピューテッドプロパティの使い方
コンピューテッドプロパティは下記場面で使う。
- 他の値から計算したい時
- 常に値を最新の状態にしたい時
- 「値の出し入れ」や「入れ方」を自分で決めたい時
それぞれ説明していこう。
1. 他の値から計算したい時
たとえば、「身長」と「体重」から「BMI」を出したいとき、わざわざBMIを保存しなくても、下記のように書けば毎回自動で計算できる。
1 2 3 4 5 6 7 8 | struct Person { var height: Double // 単位: メートル var weight: Double // 単位: キログラム var bmi: Double { return weight / (height * height) } } |
ここでは bmi
がコンピューテッドプロパティで weight
とheight
の値を使ってBMIを計算し、その計算結果を返している、
このように他の値から自動で出せるものは、コンピューテッドプロパティにすると便利である。
2. 常に値を最新の状態にしたい時
コンピューテッドプロパティは常に最新の状態にしたい情報にも向いている。
たとえば、現在の日付と誕生日から「今の年齢」を出したいとする。
この「年齢」は毎日変わるので、保存しておくよりも毎回計算する方が正確である。
1 2 3 4 5 6 7 8 9 10 11 | struct Person { var name: String var birthday: Date var age: Int { let calendar = Calendar.current let now = Date() let ageComponents = calendar.dateComponents([.year], from: birthday, to: now) return ageComponents.year ?? 0 } } |
このage
(年齢)は、その時の日時を使って毎回自動で計算される。
これなら「毎年更新する」のを忘れる心配もなく、常に最新の年齢を表示できる。
このように「変わる可能性がある情報」や「いつも今の状態を反映させたい値」は、コンピューテッドプロパティで計算するのがぴったりである。
3. 「値の出し方」や「入れ方」を自分で決めたいとき
コンピューテッドプロパティはget
(取り出すとき)とset
(設定するとき)を使って、ルールを自分で決めることができる。
たとえば、半径と直径のように、お互いに関係のある値を変えたいときに役立つ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | struct Circle { var radius: Double // 半径 var diameter: Double { // 直径 get { return radius * 2 } set { radius = newValue / 2 } } } // 使用例 var circle = Circle(radius: 5.0) print("最初の半径: \(circle.radius)") // 5.0 print("最初の直径: \(circle.diameter)") // 10.0 // 直径を変更する circle.diameter = 20.0 // 半径が自動で更新されている print("新しい半径: \(circle.radius)") // 10.0 print("新しい直径: \(circle.diameter)") // 20.0 |
このコードでは、「直径(diameter)
」は「半径(radius)
× 2」で計算される。
ただし、「直径(diameter
)」自体に新しく値を設定すると、それに合わせて「半径(radius
)」も自動で変わるようになっている。
関連した2つの値をセットで扱いたいときにとても便利である。
注意点
コンピューテッドプロパティは毎回計算されるので「処理が重たい計算」は注意が必要である。
必要に応じて、普通のプロパティで保存しておいた方がよい場合もある。
まとめ
コンピューテッドプロパティは、「計算で出せる値」をわざわざ保存せずに簡単に取り出せるようにする便利な仕組みである。
使うことで、コードがスッキリして見やすくなり、ミスも減らせる。
最初はとっつきにくいかもしれないが、慣れると「ここはコンピューテッドプロパティを使おう」と自然に思えるようになるはずだ。