การนำกลับมาใช้ใหม่และข้อจำกัด
ออกแบบตัวห่อหุ้มแบบเจเนอริกด้วย ข้อจำกัดของชนิด (เช่น Value: Comparable ) เพิ่ม API ที่เจาะจงด้วย where และประกอบตัวห่อหุ้มหลายตัวเข้าด้วยกัน
การนำกลับมาใช้ใหม่และข้อจำกัด เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 3 บทเรียน
เหตุใดจึงต้องมีข้อจำกัด
เขียนตัวห่อหุ้มเพียงหนึ่งแบบ แล้วนำกลับมาใช้กับหลายชนิดข้อมูล โดยทำให้เป็นแบบทั่วไปด้วย ข้อจำกัด เพิ่มส่วนติดต่อการใช้งานที่มุ่งเน้นด้วย เงื่อนไข และประกอบตัวห่อหุ้มขนาดเล็กเข้าด้วยกัน
แบบทั่วไป + เปรียบเทียบได้
ใช้ ความสามารถในการเปรียบเทียบ เพื่อให้ Bounded หนึ่งแบบทำงานกับ จำนวนเต็ม ข้อความ และชนิดอื่น ๆ ได้ ชนิดข้อมูลที่ไม่ถูกต้องจะถูกปฏิเสธตั้งแต่เวลาคอมไพล์
@propertyWrapper
struct Bounded<Value: Comparable> {
private var value: Value
private let range: ClosedRange<Value>
var wrappedValue: Value {
get { value }
set {
// clamp using Comparable
if newValue < range.lowerBound { value = range.lowerBound }
else if newValue > range.upperBound { value = range.upperBound }
else { value = newValue }
}
}
init(wrappedValue: Value, _ range: ClosedRange<Value>) {
self.range = range
self.value = min(max(wrappedValue, range.lowerBound), range.upperBound)
}
}
struct Stats {
@Bounded(0...100) var score: Int = 120
@Bounded("a"..."z") var letter: String = "Swift"
}
var st = Stats()
print(st.score) // 100
st.letter = "m"
print(st.letter)ส่วนขยายที่มีข้อจำกัด
ใช้ เงื่อนไข เพื่อเสนอความสามารถเพิ่มเติมเฉพาะเมื่อชนิดข้อมูลนั้นรองรับ เช่น ธงจำนวนเต็มหรือการอัปเดตเลขทศนิยม
extension Bounded where Value: BinaryInteger {
var isMaxed: Bool { wrappedValue == range.upperBound }
}
extension Bounded where Value: FloatingPoint {
mutating func bump(by delta: Value) { wrappedValue = wrappedValue + delta }
}
struct Meter {
@Bounded(0...10) var steps: Int = 9
@Bounded(0.0...1.0) var progress: Double = 0.25
}
var m = Meter()
print(m.$steps) // projectedValue not defined; accessing wrapper is not allowed directly here
print(m._steps) // compiler creates backing storage name; shown for illustration only
print(m.steps) // 9
print(m._progress) // backing storage (illustrative)
m._progress.bump(by: 0.6)
print(m.progress) // 0.85 (clamped if exceeded)ตัวห่อหุ้มสำหรับคอลเลกชันเท่านั้น
จำกัดส่วนติดต่อการใช้งานให้ใช้ได้กับ คอลเลกชัน โดยกำหนดข้อจำกัดเป็น RangeReplaceableCollection ใช้ได้กับ ข้อความ และ อาร์เรย์
@propertyWrapper
struct MaxLength<Value: RangeReplaceableCollection> where Value.Element: Sendable {
private var storage: Value
private let limit: Int
var wrappedValue: Value {
get { storage }
set {
var v = newValue
if v.count > limit { v.removeLast(v.count - limit) }
storage = v
}
}
init(wrappedValue: Value, _ limit: Int) {
self.limit = limit
self.storage = wrappedValue
if storage.count > limit { storage.removeLast(storage.count - limit) }
}
}
struct Post {
@MaxLength(10) var title: String = "hello swift learners"
@MaxLength(5) var tags: [String] = ["swift","ios","spm"]
}
var p = Post()
print(p.title) // "hello swif"
print(p.tags) // ["swift","ios","spm"]การประกอบตัวห่อหุ้ม
คุณสามารถ ซ้อน ตัวห่อหุ้มขนาดเล็กเข้าด้วยกันได้ ในตัวอย่างนี้ Trimmed จะทำงานก่อน จากนั้น NonEmpty จะรับรองว่ามีค่าสำรอง
@propertyWrapper
struct Trimmed {
private var s: String = ""
var wrappedValue: String {
get { s }
set { s = newValue.trimmingCharacters(in: .whitespacesAndNewlines) }
}
init(wrappedValue: String) { self.wrappedValue = wrappedValue }
}
@propertyWrapper
struct NonEmpty {
private var s: String = ""
var wrappedValue: String {
get { s }
set { s = newValue.isEmpty ? "N/A" : newValue }
}
init(wrappedValue: String) { self.wrappedValue = wrappedValue }
}
struct Profile {
@NonEmpty @Trimmed var displayName: String = " "
}
var prof = Profile()
print(prof.displayName) // "N/A"ตัวแปรภายในและการนำกลับมาใช้
ตัวห่อหุ้มยังใช้กับ ตัวแปรภายใน ได้ด้วย ควรทำให้เป็นแบบทั่วไปเพื่อให้ใช้ซ้ำข้ามโมดูลได้
@propertyWrapper
struct Default<Value> {
private var value: Value
private let make: () -> Value
var wrappedValue: Value {
get { value }
set { value = newValue }
}
init(wrappedValue: Value, _ factory: @escaping () -> Value) {
self.value = wrappedValue
self.make = factory
}
mutating func reset() { value = make() }
}
// Local variable usage
do {
@Default({ 0 }) var counter: Int = 5
print(counter) // 5
_counter.reset()
print(counter) // 0
}ข้อจำกัดขณะคอมไพล์ของตัวห่อหุ้ม
ตรวจสอบอย่างรวดเร็ว: คุณจะจำกัดตัวห่อหุ้มให้ใช้ได้กับชนิดข้อมูลที่เปรียบเทียบได้อย่างไร
สรุปทบทวน
สรุปทบทวน: ทำให้ตัวห่อหุ้มเป็นแบบ ทั่วไป เพิ่ม ข้อจำกัด เพื่อให้ใช้งานได้อย่างปลอดภัย เปิดเผยส่วนติดต่อการใช้งานเฉพาะด้านด้วย เงื่อนไข และ ประกอบ ตัวห่อหุ้มขนาดเล็กเพื่อให้โค้ดชัดเจน
คำถามที่พบบ่อย
บทเรียน “การนำกลับมาใช้ใหม่และข้อจำกัด” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การนำกลับมาใช้ใหม่และข้อจำกัด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 3 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การนำกลับมาใช้ใหม่และข้อจำกัด”
ออกแบบตัวห่อหุ้มแบบเจเนอริกด้วย ข้อจำกัดของชนิด (เช่น Value: Comparable ) เพิ่ม API ที่เจาะจงด้วย where และประกอบตัวห่อหุ้มหลายตัวเข้าด้วยกัน คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 3 บทเรียน
บทเรียน “การนำกลับมาใช้ใหม่และข้อจำกัด” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม
ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การสร้างตัวห่อหุ้มและ projectedValue
- การนำกลับมาใช้ใหม่และข้อจำกัด
- รูปแบบตัวห่อหุ้มที่ใช้บ่อย (การตรวจสอบความถูกต้อง การแคช)