ラッパーとprojectedValueの作成
カスタムラッパーを構築し、 wrappedValue を設定して、 projectedValue ( $ )でメタデータやヘルパーを公開します。
「ラッパーとprojectedValueの作成」はCoddyKit上の無料Swift Academyレッスンです。 これはレッスン1/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSwift Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Swift Academyコースには全3レッスンが含まれています。
プロパティラッパーを使う理由
プロパティラッパーは、プロパティの保存方法や読み取り方法を管理する再利用可能な型です:
- wrappedValue: 公開される値
- projectedValue:
$を介して提供する追加API - イニシャライザーや引数による設定
範囲制限と投影フラグ
@Clampedは数値を範囲内に制限します。projectedValue($hp)によって、直前の設定値が範囲制限されたかどうかが分かります。
@propertyWrapper
struct Clamped {
private var value: Int
private let range: ClosedRange<Int>
private(set) var wasClampedLastSet = false
var wrappedValue: Int {
get { value }
set {
let clamped = min(max(newValue, range.lowerBound), range.upperBound)
wasClampedLastSet = (clamped != newValue)
value = clamped
}
}
var projectedValue: Bool { wasClampedLastSet } // $prop -> was it clamped?
init(wrappedValue: Int, range: ClosedRange<Int>) {
self.range = range
let clamped = min(max(wrappedValue, range.lowerBound), range.upperBound)
self.value = clamped
self.wasClampedLastSet = (clamped != wrappedValue)
}
}
struct Player {
@Clamped(range: 0...100) var hp: Int = 120 // init clamps to 100
}
var p = Player()
print(p.hp) // 100
p.hp = -5
print(p.hp, p.$hp) // 0 true (was clamped)正規化と別のビュー
ラッパーは入力を変換できます(トリミングや小文字化など)。$propertyを使うと、便利な別形式を公開できます。
@propertyWrapper
struct Normalized {
private var storage: String = ""
var wrappedValue: String {
get { storage }
set { storage = newValue.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() }
}
var projectedValue: String { storage.uppercased() } // alternate view
init(wrappedValue: String) { self.wrappedValue = wrappedValue }
}
struct User {
@Normalized var username: String = " Alice "
}
let u = User()
print(u.username) // "alice"
print(u.$username) // "ALICE" (projected)設定可能なラッパー
ラッパーに引数(例: length)を渡せます。プロパティを設定するたびに、ラッパーが書式を適用します。
@propertyWrapper
struct Padded {
private var value: String
private let length: Int
var wrappedValue: String {
get { value }
set {
let s = newValue
value = s.count >= length ? String(s.prefix(length))
: s + String(repeating: " ", count: length - s.count)
}
}
var projectedValue: Int { value.count } // current width
init(wrappedValue: String, length: Int) {
self.length = length
self.value = ""
self.wrappedValue = wrappedValue
}
}
struct Row {
@Padded(length: 6) var code: String = "AB"
}
var r = Row()
print("|\(r.code)|") // |AB |
print(r.$code) // 6$value による履歴
projectedValueを使うと、メインの値のAPIを複雑にせず、変更履歴のようなメタデータを公開できます。
@propertyWrapper
struct History<Value> {
private var value: Value
private(set) var changes: [Value] = []
var wrappedValue: Value {
get { value }
set { changes.append(value); value = newValue }
}
var projectedValue: [Value] { changes } // $prop -> previous values
init(wrappedValue: Value) { self.value = wrappedValue }
}
struct Settings {
@History var level: Int = 1
}
var s = Settings()
s.level = 2
s.level = 3
print(s.level) // 3
print(s.$level) // [1, 2]設計の指針
ヒント:
- ラッパーは小さく、目的を絞ったものにしてください。
- $projectedValueが公開するものをドキュメント化してください。
- 純粋な変換を優先し、重い副作用は避けてください。
- 分かりやすいイニシャライザーと適切なデフォルト値を用意してください。
投影値の目的
確認問題: ラッパーで$propertyは何に使いますか?
まとめ
まとめ: wrappedValueを使って@propertyWrapperを実装し、projectedValue($)を通じてヘルパー、フラグ、履歴を公開します。動作はイニシャライザーで設定できます。
よくある質問
「ラッパーとprojectedValueの作成」レッスンは無料ですか?
はい。「ラッパーとprojectedValueの作成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Swift Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Swift Academyコースには全3レッスンが含まれています。
「ラッパーとprojectedValueの作成」で何を学びますか?
カスタムラッパーを構築し、 wrappedValue を設定して、 projectedValue ( $ )でメタデータやヘルパーを公開します。 ブラウザで直接実行するハンズオンコードでSwift Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Swift Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのSwift Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/3です。
「ラッパーとprojectedValueの作成」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このSwift Academyレッスンでコードを書いて実行できますか?
はい。すべてのSwift Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- ラッパーとprojectedValueの作成
- 再利用性と制約
- よく使うラッパーのパターン(検証、キャッシュ)