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

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. พื้นฐานฟังก์ชันและลายเซ็น
  2. ค่าที่ส่งคืนหลายค่า
  3. ฟังก์ชันแบบรับอาร์กิวเมนต์ไม่จำกัดจำนวน
  4. defer ฟังก์ชันไม่ระบุชื่อ และคลอสเชอร์
← กลับไปที่ Go Academy