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)