「型?プロパティ?メソッド?クロージャ?」を“見た瞬間に”見分けられるように。 すべての項目に、コードと“完全分解”表を付けました。
- 0. まずは地図:情報か?動作か?
- 1. 型(Type)とは:設計図そのもの
- 2. プロパティ(Property):情報を持つ箱
- 3. メソッド(Method):型に属する「動作」
- 4. イニシャライザ(Initializer):実体を作る特別なメソッド
- 5. クロージャ(Closure):その場で書ける“小さな関数”
- 6. オプショナル(Optional):値が“ないかも”を型で表す
- 7. 拡張(Extension):既存の型に“後から”機能追加
- 📝 完全分解(extension String { var dogBark: String { ... } })
- 8. FileManager の“超”完全分解(再掲)
- 9. プロトコル(Protocol):できることの“約束”
- 10. ジェネリクス(Generics):型に依存しない汎用コード
- 11. エラー処理:throws / try / do-catch
- 12. おまけ:配列の高階関数(手触りで“関数=動作”に慣れる)
0. まずは地図:情報か?動作か?
- 情報を持つもの → プロパティ(変数・定数のように値をしまう箱)
- 動作をするもの → メソッド(型の中の関数)
- 設計図 → 型(struct / class / enum など)
- 設計図から作る実体 → インスタンス
見分けの合言葉:「これは“箱”か、“動作”か?」
1. 型(Type)とは:設計図そのもの
サンプル
struct Dog { // Dog という「型」(設計図)
var name: String
}
let pochi = Dog(name: "ポチ") // 設計図から作った実体=インスタンス
完全分解
| 断片 | 種別 | 役割 |
|---|---|---|
struct | キーワード | 構造体(値型)の定義を始める合図 |
Dog | 型名 | 新しい型の名前(設計図の名前) |
{ ... } | ブロック | 型に属するプロパティやメソッドを書く場所 |
var name: String | プロパティ宣言 | この型の各インスタンスが持つ「名前」という情報 |
Dog(name: "ポチ") | イニシャライズ | 設計図から実体(インスタンス)を作る |
2. プロパティ(Property):情報を持つ箱
サンプル
struct User {
// 格納プロパティ(値をそのまま保持)
var name: String
// 計算プロパティ(計算して返す)
var greeting: String { "こんにちは、\(name)" }
// 遅延プロパティ(初アクセス時に初期化)
lazy var cache = HeavyLoader.load()
// 型プロパティ(インスタンス不要、型に属する)
static let species = "human"
}
完全分解(static let species = "human" 例)
| 断片 | 種別 | 役割 |
|---|---|---|
static | 修飾子 | 型に属するメンバ(インスタンス不要) |
let | キーワード | 変更不可の定数プロパティ |
species | 識別子 | プロパティ名 |
= "human" | 代入 | 初期値 |
見分け方:
var/letで始まったらプロパティ。“箱”。staticが付けば型プロパティ。
3. メソッド(Method):型に属する「動作」
サンプル
struct Dog {
var name: String
// インスタンスメソッド(インスタンスが必要)
func bark() { print("\(name)がワン!") }
// 型メソッド(インスタンス不要、型に属する)
static func info() { print("犬は哺乳類です") }
}
let pochi = Dog(name: "ポチ")
pochi.bark() // 実体に対して“動作”する
Dog.info() // 型そのものに対して“動作”する // 型メソッド(設計図そのものに命令)
完全分解(pochi.bark())
| 断片 | 種別 | 役割 |
|---|---|---|
pochi | 変数(インスタンス) | Dog 型の実体 |
. | 演算子 | 所属するメンバへアクセス |
bark | インスタンスメソッド名 | 実体の動作 |
() | 呼び出し | メソッドを実行する合図 |
見分け方:
funcで始まったらメソッド。“動作”。static/class funcなら型メソッド。
4. イニシャライザ(Initializer):実体を作る特別なメソッド
サンプル
struct Dog {
var name: String
init(name: String) { self.name = name }
}
let pochi = Dog(name: "ポチ")
完全分解(init(name: String) { self.name = name })
| 断片 | 種別 | 役割 |
|---|---|---|
init | キーワード | イニシャライザの宣言開始 |
(name: String) | パラメータ | 作成時に必要な情報 |
{ self.name = name } | 本体 | 渡された値をプロパティへ格納 |
self | 参照 | いま初期化している自分自身のインスタンス |
5. クロージャ(Closure):その場で書ける“小さな関数”
サンプル
let square: (Int) -> Int = { x in x * x }
print(square(4)) // 16
// 即時実行クロージャ:作ってすぐ呼ぶ
let greeting: String = {
let name = "太郎"
return "こんにちは、\(name)さん"
}()
完全分解(let square: (Int) -> Int = { x in x * x })
| 断片 | 種別 | 役割 |
|---|---|---|
let square | 定数宣言 | クロージャをしまう“箱”の名前 |
: (Int) -> Int | 型注釈 | 「Int を受け取って Int を返す」関数型 |
= | 代入 | 右側のクロージャを代入 |
{ x in x * x } | クロージャ式 | x を受け取り x*x を返す動作 |
完全分解(即時実行 { ... }())
| 断片 | 種別 | 役割 |
|---|---|---|
{ ... } | クロージャ | 小さな関数の本体 |
() | 呼び出し | いま作ったクロージャをその場で実行 |
なるほど!
すでに「Swift基礎まとめ記事(型・プロパティ・メソッド・クロージャ・オプショナル…など完全分解つき)」があって、そこに 「SwiftUI の中かっこの正体=クロージャ引数」 の解説を追加したいわけですね。
既存記事の流れ(5. クロージャ → 6. オプショナル…)に自然に溶け込むよう、「クロージャの実例(関数型) → SwiftUIでの応用(引数にクロージャを渡す省略記法)」 の流れで追記できる形にしました
クロージャの応用:SwiftUI の「中かっこ記法」はクロージャ引数
クロージャは「その場で書ける小さな関数」です。
SwiftUI の VStack { ... } や NavigationStack { ... } で登場する 中かっこ { ... } も、実は クロージャを引数に渡しているだけです。
普段の省略版
NavigationStack {
Text("Hello")
}
等価な明示版
NavigationStack(content: {
Text("Hello")
})
NavigationStack自体は View(構造体){ ... }は content 引数に渡されるクロージャ
👉 SwiftUI では「TypeName { … }」は「TypeName(content: { … })」に展開できると思えばOK。
VStack の場合
VStack(alignment: .leading, spacing: 16) {
Text("左寄せ1")
Text("左寄せ2")
}
= 展開すると
VStack(
alignment: .leading,
spacing: 16,
content: {
Text("左寄せ1")
Text("左寄せ2")
}
)
- alignment … 配置(leading = 左寄せ)
- spacing … 子ビュー間の余白
- content: { … } … 実際に並べるビューを返すクロージャ
モディファイアでも同じ仕組み
.sheet(isPresented: $show) {
DetailView()
}
// = .sheet(isPresented: $show, content: { DetailView() })
.alert("エラー", isPresented: $showErr) {
Button("OK", role: .cancel) {}
}
// = .alert("エラー", isPresented: $showErr, actions: { Button("OK", role: .cancel) {} })
まとめ
- 中かっこ
{ ... }は「引数に渡すクロージャ」 - Type 自体がクロージャではない
- 見慣れた
VStack { ... }やNavigationStack { ... }も、省略を外せばVStack(content: { ... })と同じ
つまり「SwiftUIの中かっこ = クロージャ応用の実例」として理解すれば、Swift文法とUIコードがつながります。
6. オプショナル(Optional):値が“ないかも”を型で表す
サンプル
var name: String? = nil // ない かもしれない
name = "花子"
// 安全な取り出し(アンラップ)
if let value = name { print(value) }
// 強制取り出し(危険)
print(name!) // nil ならクラッシュ
完全分解(if let value = name { ... })
| 断片 | 種別 | 役割 |
|---|---|---|
if let | 構文 | オプショナルを安全に取り出す(nil なら中へ入らない) |
value | 変数 | 取り出した実体(非オプショナル) |
= name | 代入 | 元のオプショナルからコピー |
合言葉:
?は「無いかも」、!は「絶対ある!(無かったら落ちる)」
7. 拡張(Extension):既存の型に“後から”機能追加
サンプル
// String 型を拡張して「犬の鳴き声」を追加
extension String {
var dogBark: String {
return self + "がワン!"
}
}
let name = "ポチ"
print(name.dogBark) // → 「ポチがワン!」
📝 完全分解(extension String { var dogBark: String { ... } })
| 断片 | 種別 | 役割 |
|---|---|---|
extension String | 宣言 | 既存の String 型に機能を追加します |
var dogBark: String | インスタンスプロパティ | String の各インスタンスが持てる「情報」を追加 |
: String | 型注釈 | このプロパティの返り値は String 型 |
{ return self + "がワン!" } | 本体 | self(この文字列自身)に「がワン!」を足して返す |
8. FileManager の“超”完全分解(再掲)
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
| 断片 | 種別 | 役割 |
|---|---|---|
FileManager | 型(class) | ファイル/フォルダ操作の窓口 |
.default | 型プロパティ | 共有の FileManager インスタンス |
.urls(for:in:) | インスタンスメソッド | 指定ディレクトリの URL 配列を取得 |
.documentDirectory | ネスト enum 値 | 「ドキュメントフォルダ」を指す選択肢 |
.userDomainMask | ネスト OptionSet 値 | 「ユーザー領域」を指す選択肢 |
.first | プロパティ | 配列の先頭要素(Optional) |
! | 演算子 | 強制アンラップ:URL?→URL(nil ならクラッシュ) |
流れ:型 → 共有インスタンス → メソッド実行 → 配列 → 先頭要素 → 強制取り出し。
9. プロトコル(Protocol):できることの“約束”
サンプル
protocol Greeter { func greet() -> String }
struct Person: Greeter { func greet() -> String { "Hi" } }
完全分解
| 断片 | 種別 | 役割 |
|---|---|---|
protocol Greeter | 宣言 | 「挨拶できること」を約束する仕様 |
{ func greet() -> String } | 要件 | 実装すべきメソッド |
struct Person: Greeter | 準拠 | Person は Greeter の約束を守る |
func greet() -> String { ... } | 実装 | 実際の動作を提供 |
10. ジェネリクス(Generics):型に依存しない汎用コード
サンプル
func maxOf<T: Comparable>(_ a: T, _ b: T) -> T { a < b ? b : a }
maxOf(3, 5) // 5
maxOf("a", "b") // "b"
完全分解
| 断片 | 種別 | 役割 |
|---|---|---|
<T: Comparable> | 型パラメータ | どんな型でもOK。ただし比較できる(Comparable)こと |
(_ a: T, _ b: T) | 引数 | 同じ型 T の2つの値 |
-> T | 返り値 | T 型を返す |
a < b ? b : a | 本体 | 大きい方を選んで返す |
11. エラー処理:throws / try / do-catch
サンプル
func loadData() throws -> String { "OK" } // 失敗するかも、と宣言
do {
let s = try loadData() // 失敗可能なので try が必要
print(s)
} catch {
print("エラー:", error)
}
let maybe = try? loadData() // 失敗したら nil
let must = try! loadData() // 失敗しないと信じる(失敗でクラッシュ)
完全分解(do { let s = try loadData() } catch { ... })
| 断片 | 種別 | 役割 |
|---|---|---|
do { ... } | 構文 | ここでエラーが出るかもしれない処理を包む |
try | キーワード | 失敗可能な関数を呼ぶときの印 |
catch { ... } | 構文 | 失敗したときの処理 |
12. おまけ:配列の高階関数(手触りで“関数=動作”に慣れる)
let arr = [1,2,3]
let doubled = arr.map { $0 * 2 } // [2,4,6]
let even = arr.filter { $0 % 2 == 0 } // [2]
let sum = arr.reduce(0, +) // 6
完全分解(arr.map { 完全分解(arr.map { $0 * 2 })
* 2 })
arr.map { $0 * 2 })| 断片 | 種別 | 役割 |
|---|---|---|
arr | 変数 | 元の配列 |
.map | メソッド | 各要素に処理を適用して新しい配列を作る“動作” |
{ $0 * 2 } | クロージャ | 受け取った要素($0)を2倍にする処理 |
最後に:見分けのルール(暗記カード)
var/let→ プロパティ(情報=箱)func→ メソッド(動作)static/class→ 型に属する(インスタンス不要)init→ 実体を作る特別メソッド{ ... }→ クロージャ、{ ... }()は即時実行?/!→ オプショナル(無いかも / 強制取り出し).の左側は 「いま誰に話しかけているか」:型?インスタンス?
迷ったら「これは箱?それとも動作?」「型に話しかけてる?インスタンスに話しかけてる?」の2つを確認!

コメント