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

การสร้างตัวห่อหุ้มและ projectedValue

สร้างตัวห่อหุ้มแบบกำหนดเอง ตั้งค่า wrappedValue และเปิดเผยข้อมูลกำกับ/ตัวช่วยด้วย projectedValue ( $ )

การสร้างตัวห่อหุ้มและ projectedValue เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 3 บทเรียน

เหตุผลที่ใช้ตัวห่อหุ้มคุณสมบัติ

ตัวห่อหุ้มคุณสมบัติคือชนิดที่นำกลับมาใช้ซ้ำได้ ซึ่งจัดการวิธีจัดเก็บและอ่านคุณสมบัติ:

  • wrappedValue: ค่าสาธารณะ
  • projectedValue: ส่วนติดต่อเพิ่มเติมผ่าน $
  • กำหนดค่าผ่านตัวเริ่มต้นหรืออาร์กิวเมนต์

Clamped และแฟล็กที่ส่งออก

@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)

ตัวห่อหุ้มที่กำหนดค่าได้

ส่งอาร์กิวเมนต์ให้ตัวห่อหุ้ม (เช่นความยาว) ตัวห่อหุ้มจะจัดรูปแบบทุกครั้งที่คุณกำหนดค่าคุณสมบัติ

@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เพื่อเปิดเผยข้อมูลกำกับ เช่น ประวัติการเปลี่ยนแปลง โดยไม่ทำให้ส่วนติดต่อของค่าหลักรกรุงรัง

@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 ใช้ทำอะไร

ทบทวน

ทบทวน: นำ @propertyWrapper ไปใช้ร่วมกับwrappedValue เปิดเผยตัวช่วย/แฟล็ก/ประวัติผ่านprojectedValue ($) และกำหนดพฤติกรรมผ่านตัวเริ่มต้น

คำถามที่พบบ่อย

บทเรียน “การสร้างตัวห่อหุ้มและ projectedValue” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การสร้างตัวห่อหุ้มและ projectedValue” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 3 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การสร้างตัวห่อหุ้มและ projectedValue”

สร้างตัวห่อหุ้มแบบกำหนดเอง ตั้งค่า wrappedValue และเปิดเผยข้อมูลกำกับ/ตัวช่วยด้วย projectedValue ( $ ) คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 3 บทเรียน

บทเรียน “การสร้างตัวห่อหุ้มและ projectedValue” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม

ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

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