0Pricing
Swift Academy · บทเรียน

การนำกลับมาใช้ใหม่และข้อจำกัด

ออกแบบตัวห่อหุ้มแบบเจเนอริกด้วย ข้อจำกัดของชนิด (เช่น 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การสร้างตัวห่อหุ้มและ projectedValue
  2. การนำกลับมาใช้ใหม่และข้อจำกัด
  3. รูปแบบตัวห่อหุ้มที่ใช้บ่อย (การตรวจสอบความถูกต้อง การแคช)
← กลับไปที่ Swift Academy