Tworzenie wrapperów, projectedValue
Zbuduj własny wrapper, skonfiguruj wrappedValue i udostępnij metadane/helpery za pomocą projectedValue ( $ ).
Tworzenie wrapperów, projectedValue to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 1 z 3. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 3 lekcji w sumie.
Dlaczego opakowania właściwości?
Opakowanie właściwości to typ wielokrotnego użytku, który zarządza sposobem przechowywania i odczytywania właściwości:
- wrappedValue: wartość publiczna
- projectedValue: dodatkowe API za pomocą
$ - Konfiguracja za pomocą inicjalizatorów/argumentów
@Clamped i flaga wartości projekcji
@Clamped ogranicza liczbę do określonego zakresu. Wartość projekcji ($hp) informuje, czy ostatnie przypisanie spowodowało ograniczenie.
@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)Normalizacja i widok alternatywny
Opakowania mogą przekształcać dane wejściowe (przycinać białe znaki/zmieniać litery na małe). $property może udostępniać wygodną formę alternatywną.
@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)Konfigurowalne opakowanie
Do opakowań można przekazywać argumenty (np. length). Opakowanie stosuje formatowanie przy każdym ustawieniu właściwości.
@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) // 6Historia za pomocą $value
Należy używać projectedValue, aby udostępniać metadane, takie jak historia zmian, bez zaśmiecania głównego API wartości.
@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]Wskazówki projektowe
Wskazówki:
- Należy utrzymywać opakowania niewielkie i skupione na jednym celu.
- Należy dokumentować, co udostępnia $projectedValue.
- Należy preferować czyste transformacje i unikać ciężkich efektów ubocznych.
- Należy udostępniać przejrzyste inicjalizatory i rozsądne wartości domyślne.
Cel wartości projekcji
Szybkie sprawdzenie: Do czego służy $property w opakowaniach?
Podsumowanie
Podsumowanie: Należy zaimplementować @propertyWrapper z użyciem wrappedValue; udostępniać funkcje pomocnicze/flagi/historię przez projectedValue ($) oraz konfigurować zachowanie za pomocą inicjalizatorów.
Często zadawane pytania
Czy lekcja „Tworzenie wrapperów, projectedValue” jest bezpłatna?
Tak — pełny tekst „Tworzenie wrapperów, projectedValue” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 3 lekcji w sumie.
Co nauczysz się w „Tworzenie wrapperów, projectedValue”?
Zbuduj własny wrapper, skonfiguruj wrappedValue i udostępnij metadane/helpery za pomocą projectedValue ( $ ). Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Swift Academy?
Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 3.
Ile czasu zajmuje lekcja „Tworzenie wrapperów, projectedValue”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?
Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Tworzenie wrapperów, projectedValue
- Możliwość ponownego użycia i ograniczenia
- Typowe wzorce wrapperów (walidacja, buforowanie)