Swift Academy · บทเรียน

defer กับข้อผิดพลาดและการคืนค่าก่อนกำหนด

รับรองว่าการคืนทรัพยากรจะเกิดขึ้นแม้มีการโยนข้อผิดพลาดหรือคืนค่าก่อนกำหนด

บทเรียน 4 จาก 413 ขั้นตอน

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

defer ทำงานเมื่อคืนค่า

บล็อก defer จะทำงานแม้ฟังก์ชันจะสิ้นสุดก่อนกำหนดผ่าน return

func check(_ value: Int) {
    defer { print("cleanup ran") }
    if value < 0 {
        print("negative, returning early")
        return
    }
    print("value is", value)
}
check(-5)

การเก็บกวาดในทุกเส้นทาง

ไม่ว่า return รายการใดจะทำงาน การเก็บกวาดที่เลื่อนการทำงานไว้จะทำงานเพียงครั้งเดียวเสมอ

func classify(_ n: Int) {
    defer { print("done classifying") }
    if n == 0 { print("zero"); return }
    if n > 0 { print("positive"); return }
    print("negative")
}
classify(0)

defer ทำงานเมื่อโยนข้อผิดพลาด

เมื่อฟังก์ชันโยนข้อผิดพลาด คำสั่ง defer ที่ลงทะเบียนไว้จะยังทำงานขณะที่ขอบเขตกำลังคลายตัว

enum MyError: Error { case bad }
func risky(_ fail: Bool) throws {
    defer { print("cleanup on the way out") }
    if fail { throw MyError.bad }
    print("no failure")
}
try? risky(true)

การทำงานร่วมกันของ return และการโยนข้อผิดพลาด

ไม่ว่าฟังก์ชันจะคืนค่าตามปกติหรือโยนข้อผิดพลาด defer เดียวกันจะทำงาน

enum E: Error { case oops }
func op(_ flag: Bool) throws -> Int {
    defer { print("op finishing") }
    if flag { throw E.oops }
    return 42
}
let r = try? op(false)
print(r ?? -1)

เก็บกวาดก่อนเผยแพร่ข้อผิดพลาด

defer จะทำงานก่อนที่ข้อผิดพลาดที่ถูกโยนจะไปถึงผู้เรียก ดังนั้นทรัพยากรจึงถูกปล่อยก่อน

enum E: Error { case fail }
func load(_ broken: Bool) throws {
    print("open")
    defer { print("close") }
    if broken { throw E.fail }
    print("read")
}
do {
    try load(true)
} catch {
    print("caught:", error)
}

ใช้ defer ควบคุมด้วย guard

รูปแบบที่ใช้กันทั่วไปคือ รับทรัพยากร เลื่อนการเก็บกวาดด้วย defer แล้วใช้ guard กับการคืนค่าก่อนกำหนด ซึ่งยังคงกระตุ้นการเก็บกวาด

func process(_ items: [Int]) {
    print("start")
    defer { print("finished") }
    guard !items.isEmpty else {
        print("nothing to do")
        return
    }
    print("processing", items.count, "items")
}
process([])

defer กับลูปที่โยนข้อผิดพลาด

defer ภายในลูปจะทำงานเมื่อจบการวนซ้ำแต่ละครั้ง แม้คำสั่งถัดไปจะโยนข้อผิดพลาด

enum E: Error { case stop }
func loop() throws {
    for i in 1...3 {
        defer { print("end", i) }
        if i == 2 { throw E.stop }
        print("body", i)
    }
}
try? loop()

ลำดับเมื่อคืนค่าก่อนกำหนด

คำสั่ง defer หลายรายการจะยังทำงานตามลำดับ LIFO เมื่อคืนค่าก่อนกำหนด

func multi(_ skip: Bool) {
    defer { print("A") }
    defer { print("B") }
    if skip { return }
    print("body")
}
multi(true)

การบันทึกเมื่อเกิดความล้มเหลว

ใช้ defer เพื่อบันทึกการเสร็จสิ้นหรือความล้มเหลวอย่างสม่ำเสมอในทุกเส้นทางการสิ้นสุด

enum E: Error { case bad }
func attempt(_ fail: Bool) throws {
    var success = false
    defer { print("attempt success:", success) }
    if fail { throw E.bad }
    success = true
}
try? attempt(true)

การคืนสถานะเมื่อโยนข้อผิดพลาด

defer เหมาะอย่างยิ่งสำหรับย้อนกลับสถานะชั่วคราวเมื่อการดำเนินการโยนข้อผิดพลาด

enum E: Error { case fail }
func transaction(_ fail: Bool) throws {
    var inProgress = true
    defer { inProgress = false; print("inProgress:", inProgress) }
    if fail { throw E.fail }
    print("committed")
}
try? transaction(true)

แนวปฏิบัติที่ดี

พึ่งพา defer สำหรับการเก็บกวาดที่ต้องทำงานต่อแม้มีการคืนค่าก่อนกำหนดหรือข้อผิดพลาดที่ถูกโยน เพื่อไม่ให้มีเส้นทางการสิ้นสุดใดทำให้ทรัพยากรรั่วไหล

enum E: Error { case x }
func safe(_ fail: Bool) throws {
    print("acquire")
    defer { print("release") }
    if fail { throw E.x }
    print("use")
}
try? safe(true)

ตรวจสอบอย่างรวดเร็ว

ทดสอบ defer กับข้อผิดพลาดและการคืนค่า

สรุปทบทวน

defer ทำงานเมื่อออกจากขอบเขตทุกกรณี รวมถึงการใช้ return ก่อนกำหนดและข้อผิดพลาดที่ถูกโยน โดยจะทำงานก่อนที่ข้อผิดพลาดจะแพร่ต่อไป จึงเป็นตำแหน่งที่เชื่อถือได้สำหรับการเก็บกวาดและการคืนสถานะในทุกเส้นทางการสิ้นสุด พร้อมคงลำดับ LIFO ไว้

func f(_ skip: Bool) {
    defer { print("cleanup") }
    if skip { return }
    print("work")
}
f(true)
เริ่มต้นได้ฟรี

เรียนรู้ Swift ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
122
บทเรียน
409

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

บทเรียน “defer กับข้อผิดพลาดและการคืนค่าก่อนกำหนด” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “defer กับข้อผิดพลาดและการคืนค่าก่อนกำหนด”

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

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

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

บทเรียน “defer กับข้อผิดพลาดและการคืนค่าก่อนกำหนด” ใช้เวลานานแค่ไหน

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

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

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

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

  1. defer ทำงานอย่างไร
  2. ลำดับของบล็อก defer หลายบล็อก
  3. defer สำหรับการคืนทรัพยากร
  4. defer กับข้อผิดพลาดและการคืนค่าก่อนกำหนด
← กลับไปที่ Swift Academy