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

การจับค่าด้วยการอ้างอิง

ทำความเข้าใจว่าคลอเชอร์จับสถานะโดยรอบไว้อย่างไร

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

สิ่งที่ Closures จับไว้

closure จะจับตัวแปรและค่าคงที่จาก scope รอบข้างที่ closure นั้นอ้างถึง ตัวแปรที่ถูกจับไว้จะถูกเก็บโดยการอ้างอิง ดังนั้น closure จึงมองเห็นการเปลี่ยนแปลงภายหลัง

การจับค่าคงที่

closure จะจดจำ greeting ไว้ แม้ฟังก์ชันจะคืนค่าไปแล้ว:

func makeGreeter() -> () -> String {
    let greeting = "Hello"
    return { greeting }
}
let greet = makeGreeter()
print(greet())  // "Hello"

การจับตัวแปรโดยการอ้างอิง

เนื่องจาก count เป็น var closure จึงเปลี่ยนแปลงพื้นที่เก็บข้อมูลเดียวกันในการเรียกแต่ละครั้ง:

func makeCounter() -> () -> Int {
    var count = 0
    return {
        count += 1
        return count
    }
}
let next = makeCounter()
print(next(), next(), next())  // 1 2 3

พื้นที่เก็บข้อมูลร่วมกัน

closures สองตัวสามารถจับตัวแปรเดียวกันและมองเห็นการเปลี่ยนแปลงของกันและกัน:

func makePair() -> (() -> Void, () -> Int) {
    var value = 0
    let inc = { value += 1 }
    let read = { value }
    return (inc, read)
}
let (inc, read) = makePair()
inc(); inc()
print(read())  // 2

การจับสะท้อนการเปลี่ยนแปลงภายหลัง

closure จะอ่านค่าปัจจุบันของตัวแปรขณะถูกเรียก ไม่ใช่ค่าของตัวแปรในตอนสร้าง closure:

var message = "first"
let show = { print(message) }
message = "second"
show()  // "second"

การจับโดยการอ้างอิงเทียบกับการจับโดยค่า

โดยค่าเริ่มต้น ตัวแปรที่เปลี่ยนแปลงได้จะถูกจับโดยการอ้างอิง หากคุณต้องการสำเนาค่าที่หยุดนิ่ง ณ เวลาสร้าง ให้ระบุไว้ใน รายการจับ เช่น [x]

การตรึงค่า

รายการจับจะคัดลอกค่าทันที:

var n = 10
let frozen = { [n] in n }   // copies 10 now
n = 99
print(frozen())  // 10

แต่ละ Closure มีสถานะเป็นอิสระ

การเรียก factory แต่ละครั้งจะสร้างตัวแปรที่ถูกจับขึ้นมาใหม่:

func counter() -> () -> Int {
    var c = 0
    return { c += 1; return c }
}
let a = counter(), b = counter()
print(a(), a(), b())  // 1 2 1

การจับภายในลูป

หากไม่ระวัง closures ภายในลูปอาจใช้ตัวแปรเดียวกัน ใช้รายการจับเพื่อบันทึกค่าแยกกันในการวนซ้ำแต่ละครั้ง:

var closures: [() -> Int] = []
for i in 1...3 {
    closures.append { [i] in i }
}
print(closures.map { $0() })  // [1, 2, 3]

การจับ self ใน method

closure ที่สร้างภายใน method จะจับ instance รอบข้างไว้ ทำให้สามารถอ่านและเปลี่ยนแปลง property ได้ในภายหลัง:

class Bank {
    var balance = 0
    func deposit() -> () -> Void {
        return { self.balance += 10 }
    }
}
let bank = Bank()
let add = bank.deposit()
add(); add()
print(bank.balance)  // 20

เหตุใดจึงสำคัญ

การจับโดยการอ้างอิงเป็นพลังเบื้องหลังตัวนับ ตัวสะสม และ callback ที่มีสถานะ — แต่ก็หมายความว่า closure อาจทำให้ object ยังคงอยู่ต่อไป ซึ่งเราจะจัดการด้วยรายการจับในหัวข้อถัดไป

func accumulator() -> (Int) -> Int {
    var total = 0
    return { total += $0; return total }
}
let add = accumulator()
print(add(10), add(5))  // 10 15

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

โดยค่าเริ่มต้น closure จะจับตัวแปรที่เปลี่ยนแปลงได้อย่างไร

สรุป

คุณได้เรียนรู้ความหมายของการจับค่า:

  • Closures จะจับตัวแปรที่อ้างถึงจาก scope ของตน
  • ตัวแปรที่เปลี่ยนแปลงได้จะถูกจับโดยการอ้างอิง — การเปลี่ยนแปลงและการแก้ไขจะใช้ร่วมกัน
  • รายการจับ [x] จะตรึงสำเนาค่าไว้ตั้งแต่ตอนสร้าง
  • กลไกนี้เป็นพื้นฐานของตัวนับและ callback ที่มีสถานะ

ถัดไป: closures ที่หลุดออกนอกขอบเขต

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

บทเรียน “การจับค่าด้วยการอ้างอิง” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “การจับค่าด้วยการอ้างอิง”

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

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

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

บทเรียน “การจับค่าด้วยการอ้างอิง” ใช้เวลานานแค่ไหน

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

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

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

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

  1. การจับค่าด้วยการอ้างอิง
  2. คลอเชอร์ที่หลุดออกนอกขอบเขต
  3. รายการจับค่าและ weak self
  4. Autoclosures
← กลับไปที่ Swift Academy