- Published on
การกำหนด default parameter ในภาษา Go
- Authors

- Name
- Somprasong Damyos
- @somprasongd
การกำหนด default parameter ในภาษา Go
ภาษา Go ไม่มีการสนับสนุน default parameter ตรงๆ เหมือนกับภาษาอื่นๆ เช่น JavaScript แต่เราสามารถทำได้ง่ายๆ ดังนี้
ตัวอย่างเช่น ถ้าเราต้องการเขียนฟังก์ชั่นที่รับพารามิเตอร์ชื่อ name และ phoneNumber แต่หากไม่มีการส่งค่า phoneNumber เข้ามา จะกำหนดให้ phoneNumberเป็น unknown
package main
import "fmt"
func getInfo(name string, phoneNumber string) string {
if len(phoneNumber) == 0 {
phoneNumber = "unknown"
}
return fmt.Sprintf("Name: %s, Phone number: %s", name, phoneNumber)
}
func main() {
fmt.Println(getInfo("John", ""))
fmt.Println(getInfo("Jane", "+660812345678"))
}
// Output:
Name: John, Phone number: unknown
Name: Jane, Phone number: +660812345678
ใช้ variadic function
จากโค้ดก่อนหน้าจะเห็นว่า phoneNumber เราไม่จำเป็นต้องส่งไปก็ได้ (optional parameter) การจะทำแบบนั้นได้จะใช้คุณสมบัติของ variadic function มาช่วย
ซึ่ง variadic function คือฟังก์ชั่นที่สามารถรับพารามิเตอร์ที่ไม่จำกัดจำนวนได้ ดังนั้นเราสามารถเขียนฟังก์ชั่นให้รับพารามิเตอร์ตามปกติ และให้ค่า default ของพารามิเตอร์เป็นค่า zero value ของประเภทของพารามิเตอร์นั้นๆ
สามารถแก้ไขโค้ดตัวอย่างได้ดังนี้
package main
import "fmt"
func getInfo(name string, phoneNumber ...string) string {
pn := "unknown"
if len(phoneNumber) > 0 {
pn = phoneNumber[0]
}
return fmt.Sprintf("Name: %s, Phone number: %s", name, pn)
}
func main() {
fmt.Println(getInfo("John"))
fmt.Println(getInfo("Jane", "+660812345678"))
}
// Output:
Name: John, Phone number: unknown
Name: Jane, Phone number: +660812345678
ซึ่งจะได้ผลลัพธ์เหมือนกัน แต่เราไม่จำเป็นต้องส่ง phineNumber เข้าไปแล้ว แต่วิธีจะใช้ได้เมื่อต้องการ optional parameter แค่ตัวเดียว
Functional Options
สุดท้ายถ้าเราต้องการ optional parameter มากกว่า 1 ตัว เราจะใช้ functional options pattern มาช่วย
ตัวอย่างเช่น เรามี parameter 3 ตัว คือ ตัวแรก name จะต้องส่งไปทุกครั้ง และอีก 2 ตัว คือ phone number กับ email เป็น optional parameters สามารถทำได้ดังนี้
package main
import "fmt"
type InfoOptions struct {
PhoneNumber string
Email string
}
type InfoOption func(i *InfoOptions)
func WithPhoneNumber(pn string) InfoOption {
return func(i *InfoOptions) {
i.PhoneNumber = pn
}
}
func WithPhoneEmail(email string) InfoOption {
return func(i *InfoOptions) {
i.Email = email
}
}
func getInfo(name string, opts ...InfoOption) string {
opt := InfoOptions{
PhoneNumber: "unknown",
Email: "unknown",
}
for _, applyOpt := range opts {
applyOpt(&opt)
}
return fmt.Sprintf("Name: %s, Phone number: %s, Email: %s", name, opt.PhoneNumber, opt.Email)
}
func main() {
fmt.Println(getInfo("John"))
fmt.Println(getInfo("Jane", WithPhoneNumber("+660812345678")))
fmt.Println(getInfo("James", WithPhoneNumber("+660812345600"), WithPhoneEmail("james@mail.com")))
}
// Output:
Name: John, Phone number: unkonw, Email: unknown
Name: Jane, Phone number: +660812345678, Email: unknown
Name: James, Phone number: +660812345600, Email: james@mail.com
โค้ดดังกล่าวเป็นตัวอย่างการใช้งานการสร้างฟังก์ชันแบบตัวเลือก (Option pattern) ในภาษา Go โดยใช้ฟังก์ชันตัวแปรแบบ func(i *InfoOptions) ซึ่งจะรับค่า struct InfoOptions เป็นพารามิเตอร์และนำค่าของตัวแปรเข้าไปปรับปรุงในตัวแปรนั้นๆ
การทำงานของโค้ดดังกล่าวอธิบายได้ดังนี้:
- กำหนด struct ชื่อ
InfoOptionsซึ่งมี properties คือPhoneNumberและEmailเพื่อใช้ในการเก็บข้อมูลที่จะถูกส่งเข้าฟังก์ชัน - กำหนด type ชื่อ
InfoOptionที่เป็น function signature โดยฟังก์ชันนี้จะรับตัวแปรแบบ pointer ชนิดInfoOptionsและไม่มีการ return ค่า - กำหนดฟังก์ชัน
WithPhoneNumberที่จะ return ฟังก์ชันแบบตัวเลือกInfoOptionซึ่งจะรับตัวแปรเป็นเบอร์โทรศัพท์และจะอัปเดตค่าของPhoneNumberในInfoOptions - กำหนดฟังก์ชัน
WithPhoneEmailที่จะ return ฟังก์ชันแบบตัวเลือกInfoOptionซึ่งจะรับตัวแปรเป็นอีเมลและจะอัปเดตค่าของEmailในInfoOptions - กำหนดฟังก์ชัน
getInfoที่รับตัวแปรnameและopts ...InfoOptionที่เป็นตัวเลือกของInfoOptionsโดยฟังก์ชันนี้จะสร้างตัวแปรoptจากInfoOptionsโดยกำหนดค่าเริ่มต้นของPhoneNumberและEmailให้เป็น "unknown" - ใช้ loop for-range เพื่อวนรอบตามจำนวนของ
optsและเรียกใช้ฟังก์ชันตัวแปรแบบInfoOptionที่ถูกส่งเข้ามากับoptเพื่ออัปเดตค่าของInfoOptionsโดยส่ง pointer ของoptไปให้ฟังก์ชันตัวแปรแต่ละตัว - ในฟังก์ชัน
mainจะมีการเรียกใช้getInfoกับชื่อของผู้ใช้งาน และตัวเลือกที่ส่งเข้าไป เพื่อแสดงผลลัพธ์ออกทางหน้าจอ โดยมีการส่งตัวเลือกWithPhoneNumberและWithPhoneEmailสองตัวไปด้วย
จะเห็นได้ว่าโค้ดดังกล่าวนั้นเป็นการใช้งานแบบตัวเลือก (Option pattern) ซึ่งช่วยให้สามารถสร้างฟังก์ชันที่รับพารามิเตอร์ได้หลายรูปแบบ โดยไม่ต้องกำหนดหลายฟังก์ชันให้เป็น overload หรือจัดการด้วยพารามิเตอร์ default ที่ซับซ้อน นอกจากนี้ การใช้งานแบบตัวเลือกยังช่วยให้การเปลี่ยนแปลงของพารามิเตอร์ไม่มีผลต่อการเรียกใช้ฟังก์ชันที่เหลือไปและเป็นไปตามความต้องการของผู้ใช้งานได้อย่างยืดหยุ่นและสะดวกสบาย