Swift を書いていると 「クロージャ式(closure)」 と 「計算型プロパティ(computed property)」 は見た目が似ていて混乱しがち。この記事では、両者の違いを 一発で腹落ち させる表と、動くサンプルコードで解説します。そのままコピペOK です。
結論サマリ(比較表)
| クロージャ式 | 計算型プロパティ | |
|---|---|---|
| 見た目 | 関数オブジェクトを保持する変数/プロパティ | プロパティ(値のように見える) |
| 呼び方 | closure() | property(() なし) |
| 引数 | あり/なしどちらも可 | 引数なしのみ |
| 再代入 | 可能(別のクロージャに差し替え可) | 不可(ロジック固定) |
| キャプチャ | 可(外部変数を取り込める) | 基本想定しない(そのスコープ内で完結) |
| 使いどころ | 可変の処理・動的に差し替えたい処理 | 常に決まった計算を“値”として見せたいとき |
サンプル1:クロージャ式の基本(引数あり/なし、差し替え、値キャプチャ)
import Foundation
struct MathBox {
// ① 引数ありクロージャ(Int -> Int)
var transform: (Int) -> Int = { x in x * 2 }
// ② 引数なしクロージャ(() -> Int)
var constant: () -> Int = { 5 * 5 } // 25
// ③ 値キャプチャ(必要な値だけ取り込む)
private var factor: Int = 3
// 初回アクセス時点の factor を閉じ込める(struct なので [unowned self] は使わない)
lazy var multiply: (Int) -> Int = { [factor] x in
x * factor
}
}
// 使い方
var box = MathBox()
print(box.transform(10)) // 20
print(box.constant()) // 25
print(box.multiply(4)) // 12
// 差し替え(再代入できるのが強み)
box.transform = { x in x * 3 }
print(box.transform(10)) // 30
ポイント
- クロージャは「関数そのもの」を値として保管でき、実装を差し替えられる。
structのプロパティクロージャでselfを捕まえる必要があるときはlazyを付けて、必要な値だけ[factor]のように値キャプチャするのが安全。multiplyは 初回アクセス時点のfactorを固定して使います。
「いつも最新のfactorを使いたい」ならメソッドにします👇
struct MathBox2 {
private var factor = 3
mutating func setFactor(_ v: Int) { factor = v }
func multiply(_ x: Int) -> Int { x * factor }
}
参考:
classでselfをクロージャが参照する場合は循環参照対策として[unowned self]/[weak self]を使います(structには不要&不可)。
サンプル2:計算型プロパティの基本(() なし でアクセス)
import Foundation
struct Rectangle {
var width: Double
var height: Double
// 計算型プロパティ(読み取り専用)
var area: Double {
width * height
}
// 参考:setter を持たせることも可能
// var area: Double {
// get { width * height }
// set { width = sqrt(newValue); height = sqrt(newValue) }
// }
}
let r = Rectangle(width: 4, height: 5)
print(r.area) // 20 ← () を付けないのが「プロパティ」
ポイント
- 「値として見せたい」時に最適。引数は取らない。
- 毎回
getが評価されるが、呼び出し側からは ただの値 に見える。
よくあるつまずき:呼び方ミス
クロージャをプロパティにした場合
var constant: () -> Int = { 25 }
constant() // ✅ 正しい(関数呼び出し)
constant // ❌ 関数オブジェクト自体(呼んでいない)
計算型プロパティの場合
var constant: Int { 25 }
constant // ✅ 正しい(値)
constant() // ❌ コンパイルエラー(プロパティに () は不要)
Playground は「未完成の行(末尾に
.がぶら下がる等)」があると落ちやすいです。
完成させてから実行しましょう(自動実行→手動実行への切り替えも有効)。
使い分けガイド(実務感)
- 状態に応じて処理を差し替えたい
→ クロージャ式
例)戦略パターン・DI、テストでモック関数差し替え、アニメ/フィルタ切り替え - “値”として扱いたい、API を読みやすくしたい
→ 計算型プロパティ
例)user.fullName、rect.area、view.intrinsicContentSize
SwiftUIの実例(肌感覚で覚える)
1) クロージャが自然な場面(イベントハンドラ)
import SwiftUI
struct ClosureExample: View {
var body: some View {
Button("Tap me") {
// ここがクロージャ(() -> Void)
print("Tapped!")
}
}
}
2) 計算型プロパティが自然な場面(表示用の派生値)
import SwiftUI
struct User {
var firstName: String
var lastName: String
var fullName: String { "\(lastName) \(firstName)" } // 値として見せたい
}
struct PropertyExample: View {
let user = User(firstName: "太郎", lastName: "山田")
var body: some View {
Text(user.fullName) // () なしで自然に読める
}
}
もう一歩:パフォーマンスと設計の勘所
- インライン化の期待
単純な計算型プロパティは最適化されやすい。高頻度アクセスで軽い算出ならプロパティが読みやすく高速。 - DI・戦略の切替
ユースケース層や UI のイベント処理の差し替えは クロージャ が強力。テスト時に処理を注入しやすい。 - 命名で迷子を防ぐ
クロージャプロパティにはon…,handler,transform,predicateなど
「関数っぽさが伝わる名前」 を付けると呼び方ミスが減る(例:calcProFn())。
まとめ:選択基準は「値として見せたいか」「処理を差し替えたいか」
- 値として扱いたい(引数不要・読みやすさ重視)→ 計算型プロパティ
- 処理を差し替えたい / 引数を取りたい → クロージャ式
迷ったら「呼び方」で決める:() を付けたいならクロージャ、付けたくないならプロパティ。

コメント