SwiftUIのチュートリアルの文法(コンピューテッドプロパティ)について
はじめに
先日、SwiftUIが発表されて最近ちょくちょく公式チュートリアルをやっています。
2つ目のチュートリアルをやっていると、見たことのないプロパティの定義方法が出てきたので、今回はそれについてまとめてみました。
これが問題のコードです。
var locationCoordinate: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: coordinates.latitude, longitude: coordinates.longtitude) }
ぱっと見コンピューテッドプロパティっぽいですが、gettterやsetterやreturn文がありませんよね。
この問題を解決すべく、まずコンピューテッドプロパティについて簡単に説明し、その後上記のコードについて解説しようと思います。
コンピューテッドプロパティとは?
プロパティ自身が値を保持しておらず、プロパティへのアクセス時に計算した値を返すプロパティです。
ちなみに、値を保持するプロパティはストアドプロパティといいます。
プロパティの種類については以下の記事がわかりやすいです。
qiita.com
コンピューテッドプロパティは次のように使います。
import UIKit struct Circle { // ストアドプロパティ var radius: Double = 0 // コンピューテッドプロパティ var area: Double { get { return radius * radius * 3 } set { // プロパティに代入した値はnewValueでアクセス可能 radius = sqrt(newValue / 3) } } } var circle = Circle() circle.radius // 0 circle.area // 0 (getter) circle.radius = 5 circle.radius // 5 circle.area // 75 (getter) circle.area = 27 // (setter) circle.radius // 3 circle.area // 27
コンピューテッドプロパティを定義するときはget{}
でgetterを、set{}
でsetterを指定し、getterには値を返す処理を、setterには値を更新する処理を書きます。
上のコードでは、getterで半径に応じた円の面積を返す処理を、setterで円の半径を更新する処理を書いています。
ここで、コンピューテッドプロパティのgetterは必須ですが、setterは省略可能です。
import UIKit struct Circle { var radius: Double = 0 var area: Double { get{ return radius * radius * 3 } } } var circle = Circle() circle.radius // 0 circle.area // 0 (getter) circle.radius = 5 circle.radius // 5 circle.area // 75 (getter) circle.area = 27 // setterを定義していないのでコンパイルエラーになる
また、setterを省略した場合はget{}
を省略してgetterを書くこともできます。
import UIKit struct Circle { var radius: Double = 0 var area: Double { // getがなくてもgetterとして動作する return radius * radius * 3 } }
以上がこれまでのコンピューテッドプロパティの定義方法です。
スポンサーリンク
新しいコンピューテッドプロパティ?
コンピューテッドプロパティについて理解できたところで、初めのコードを見てみましょう。
var locationCoordinate: CLLocationCoordinate2D { CLLocationCoordinate2D(latitude: coordinates.latitude, longitude: coordinates.longtitude) }
これは、先程説明したsetterとget{}
を省略した形に似ていますが、return
までもが省略されています。
あれ?こんな書き方OKなの?といろいろ調べていると、以下のページが見つかりました。
ドキュメントのShorthand Getter Declarationでは次のように書かれています。
If the entire body of a getter is a single expression, the getter implicitly returns that expression.
つまり、getterの中身の式が一つだけなら、return
は書く必要がないってことです。
この暗黙的なreturn
は、短いコードのreturn
の占める割合多くね?単一式だったらreturn
書いてるってことにしようよってことで採用されたようです。
そのため、暗黙的なreturn
は関数の定義においても使えます。
func oldCircleArea(with radius: Int) -> Int { return radius * radius * 3 } func newCircleArea(with radius: Int) -> Int { radius * radius * 3 // returnを省略 } print(oldCircleArea(with: 5)) // 75 print(newCircleArea(with: 5)) // 75
まとめ
Swift5.1から関数の定義やgetterでは単一式の場合にreturn
が省略でき、コード量を減らせるようになります。
SwiftUIのチュートリアルはとてもわかりやすいのですが、文法の解説がないのがなんだかなーって感じです。
他にも気になった文法が出てくれば、調べてまとめようと思います。