DEV Community

Pallat Anchaleechamaikorn
Pallat Anchaleechamaikorn

Posted on

HOF in go

Higher Order Function คือคุณสมบัติที่ function สามารถรับ parameter หรือคืนค่าเป็น function ได้ ซึ่งจะสัมพันธ์กับเรื่อง First Class Function และสัมพันธ์กับเรื่อง Closure Function และเป็นเรื่องที่ทำให้โปรแกรมเมอร์ที่ไม่คุ้นเคยกับ concept ทำนองนี้ต้องทำความเข้าใจมากพอสมควร

เวลาผมคิดถึงเรื่อง HOF หรือ First-class จำเป็นจะต้องแยกเรื่อง literal ออกไปให้ชัด เพราะถ้าเรามัวแต่ไปจ้องที่รูปร่างหน้าตาของมัน จะทำให้งง ยกตัวอย่างเช่น

func hof(fn func(string) string) {
    ...
}

เวลาเจอแบบนี้ ให้มองให้ออกว่า ตรงไหนคือ type โดยให้เทียบกับการประกาศแบบ primitive type ธรรมดาเช่น

func normal(s string) {
    ...
}

ให้มองให้ออกว่า fn func(string) string ก็เหมือนกับ s string การจะทำให้มองสิ่งนี้ง่ายขึ้น เราจึงเห็นการสร้าง type แบบนี้

type doSumethingFunc func(string) string

func hof(fn doSumethingFunc) {
    ...
}

ในโลกของ go เราเห็น HOF บ่อยๆเวลาทำ Wrapper หรือ Middleware ยกตัวอย่างเช่น echo MiddlewareFunc จะมีหน้าตาแบบนี้

type HandlerFunc func(Context) error

type MiddlewareFunc func(HandlerFunc) HandlerFunc

เวลาจะเขียน middleware เราก็จะเห็นโค้ดหน้าตาแบบนี้

func Middleware(next echo.HandlerFunc) echo.HandlerFunc {
    return func(c echo.Context) error {
        ...
        next(c)
        ...
    }
}

วิธีมองให้ดูว่าฟังก์ชั่น Middleware เป็น HOF ที่รับ echo.HandlerFunc เป็น parameter และคือค่าออกเป็นเป็น type เดียวกับที่รับเข้ามา และด้วยเหตุนี้ ปกติใน go ก็มักจะเขียน return ค่าเป็น anonymous function ที่มีหน้าตาตรงกับ return type ซึ่ง HandlerFunc ก็คือ func(Context) error

ในฟังก์ชั่นนี้ เราสามารถเขียนสิ่งที่ต้องการทำก่อน และหลังการทำงานของ next ซึ่ง next นี่ก็คือ handler ตัวที่ทำงานเป็น business logic หลักที่เราตั้งใจเขียนให้ทำงานจริงๆ เพราะฉะนั้น ไม่ว่าเราจะทำอะไรก็ตามในฟังก์ชั่นนี้จะต้องไม่ลืมสั่งให้มันทำงานตามที่มันควรทำ ซึ่งก็คือ next(c) นั่นเอง

Top comments (0)