defer ฟังก์ชันไม่ระบุชื่อ และคลอสเชอร์
การเรียกใช้ที่เลื่อนเวลาและค่าฟังก์ชัน
defer ฟังก์ชันไม่ระบุชื่อ และคลอสเชอร์ เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
defer: การทำงานที่เลื่อนออกไป
defer กำหนดเวลาการเรียกฟังก์ชันให้ทำงานเมื่อฟังก์ชันที่ครอบอยู่ส่งค่ากลับ ไม่ว่าจะส่งค่ากลับด้วยวิธีใด (ปกติ เกิดข้อผิดพลาด หรือเกิด panic):
func readFile(path string) {
f, err := os.Open(path)
if err != nil { return }
defer f.Close() // runs when readFile returns
// read from f...
}ลำดับการประเมินของ defer
การเรียกที่ใช้ defer จะถูกใส่ไว้ในสแตกและทำงานตามลำดับแบบ LIFO (เข้าหลังออกก่อน):
func main() {
defer fmt.Println("third")
defer fmt.Println("second")
defer fmt.Println("first")
// Output: first, second, third
}ใช้ defer สำหรับการล้างทรัพยากร
defer เป็นวิธีตามสำนวนของภาษาในการรับรองว่าทรัพยากรจะถูกคืน:
- ปลดล็อกมิวเทกซ์หลังจากล็อกแล้ว
- ปิดไฟล์หลังจากเปิดแล้ว
- ยืนยันหรือย้อนกลับธุรกรรมฐานข้อมูล
- เรียก WaitGroup.Done() หลังจาก WaitGroup.Add()
defer พร้อมอาร์กิวเมนต์
อาร์กิวเมนต์ของการเรียกที่ใช้ defer จะถูกประเมินทันทีเมื่อเรียก defer ไม่ใช่เมื่อการเรียกนั้นทำงาน:
x := 10
defer fmt.Println(x) // prints 10, not 20
x = 20
fmt.Println(x) // prints 20ฟังก์ชันไม่ระบุชื่อ
ฟังก์ชันไม่ระบุชื่อ (ลิเทอรัลฟังก์ชัน) คือฟังก์ชันที่กำหนดไว้ภายในโค้ดโดยไม่มีชื่อ:
double := func(n int) int {
return n * 2
}
fmt.Println(double(5)) // 10
// Immediately invoked:
result := func(a, b int) int { return a + b }(3, 4)โคลเชอร์
โคลเชอร์คือฟังก์ชันที่เก็บค่าตัวแปรจากขอบเขตโดยรอบไว้:
func makeCounter() func() int {
count := 0
return func() int {
count++
return count
}
}
ctr := makeCounter()
fmt.Println(ctr(), ctr(), ctr()) // 1 2 3ข้อควรระวังเรื่องการเก็บค่าของโคลเชอร์ในลูป
โคลเชอร์เก็บตัวแปรโดยการอ้างอิง ซึ่งเป็นสาเหตุทั่วไปของข้อผิดพลาดในลูปที่ใช้ goroutine:
for i := 0; i < 3; i++ {
i := i // create a new variable per iteration
go func() { fmt.Println(i) }()
}defer กับค่าที่ส่งกลับแบบมีชื่อ
ฟังก์ชันที่ใช้ defer สามารถแก้ไขค่าที่ส่งกลับซึ่งมีชื่อกำกับไว้ได้ ซึ่งมีประโยชน์สำหรับการใส่ข้อมูลเพิ่มเติมให้ข้อผิดพลาด:
func doWork() (err error) {
defer func() {
if err != nil {
err = fmt.Errorf("doWork: %w", err)
}
}()
return riskyOp()
}รูปแบบเชิงฟังก์ชันด้วยโคลเชอร์
โคลเชอร์ช่วยให้ใช้รูปแบบเชิงฟังก์ชัน เช่น การจดจำผลลัพธ์ ได้:
func memoize(f func(int) int) func(int) int {
cache := map[int]int{}
return func(n int) int {
if v, ok := cache[n]; ok {
return v
}
v := f(n)
cache[n] = v
return v
}
}โคลเชอร์ในฐานะตัวกลาง
โคลเชอร์เป็นองค์ประกอบพื้นฐานสำหรับตัวกลางในเซิร์ฟเวอร์ HTTP ของ Go โดยโคลเชอร์จะครอบตัวจัดการและเพิ่มพฤติกรรมก่อนหรือหลังการทำงานของตัวจัดการ:
func withLogging(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s", r.Method, r.URL)
next(w, r)
}
}ตรวจสอบความเข้าใจ
อาร์กิวเมนต์ของการเรียกฟังก์ชันที่ใช้ defer ถูกประเมินเมื่อใด
สรุป: defer โคลเชอร์ และฟังก์ชันไม่ระบุชื่อ
ความสามารถเหล่านี้ทำให้โค้ด Go สื่อความหมายได้ดีและปลอดภัย:
deferรับรองการล้างทรัพยากรเมื่อฟังก์ชันสิ้นสุด โดยทำตามลำดับแบบ LIFO- อาร์กิวเมนต์ของ defer ถูกประเมินทันที
- ฟังก์ชันไม่ระบุชื่อสามารถกำหนดให้ตัวแปรหรือเรียกใช้โดยตรงได้
- โคลเชอร์เก็บตัวแปรโดยรอบไว้ด้วยการอ้างอิง
- ระวังข้อผิดพลาดจากการเก็บค่าตัวแปรของลูปใน goroutine
หลักสูตรถัดไป: อาร์เรย์ สไลซ์ และแมป
คำถามที่พบบ่อย
บทเรียน “defer ฟังก์ชันไม่ระบุชื่อ และคลอสเชอร์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “defer ฟังก์ชันไม่ระบุชื่อ และคลอสเชอร์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “defer ฟังก์ชันไม่ระบุชื่อ และคลอสเชอร์”
การเรียกใช้ที่เลื่อนเวลาและค่าฟังก์ชัน คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “defer ฟังก์ชันไม่ระบุชื่อ และคลอสเชอร์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- พื้นฐานฟังก์ชันและลายเซ็น
- ค่าที่ส่งคืนหลายค่า
- ฟังก์ชันแบบรับอาร์กิวเมนต์ไม่จำกัดจำนวน
- defer ฟังก์ชันไม่ระบุชื่อ และคลอสเชอร์