การจับค่าด้วยการอ้างอิง
ทำความเข้าใจว่าคลอเชอร์จับสถานะโดยรอบไว้อย่างไร
การจับค่าด้วยการอ้างอิง เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การจับค่าด้วยการอ้างอิง
- คลอเชอร์ที่หลุดออกนอกขอบเขต
- รายการจับค่าและ weak self
- Autoclosures