- Published on
การใช้งาน Enum ใน Go
- Authors
- Name
- Somprasong Damyos
- @somprasongd
การใช้งาน Enum ใน Go
Enum คือ การสร้างกลุ่มของข้อมูลมูลขึ้นมาเป็นค่าคงที่ที่มีความหมาย และทำให้เราอ่านโค้ดได้เข้าใจง่ายขึ้น โดยการประกาศ enum ในภาษา Go จะใช้ const
ของ int
หรือ string
เพื่อสร้างขึ้นมา เช่น
// string mapping
const (
Sunday string = "sunday "
Monday = "monday"
Tuesday = "tuesday"
Wednesday = "wednesday"
Thursday = "thursday"
Friday = "friday"
Saturday = "saturday"
)
// int mapping
const (
Sunday int = 0
Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Saturday = 6
)
แต่เพื่อให้โค้ดของเราอ่านง่ายขึ้น แนะนำให้สร้าง enum ร่วมกับ iota
แทน โดยจะมีค่าเริ่มต้นที่ 0 ตัวถัดๆ ไปจะ +1 ไปเรื่อยๆ
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
แต่การเอา enum ไปใช้งานแบบนี้อาจทำให้เกิดข้อผิดพลาดได้ เช่น การเอาไปเปรียบเทียบค่าว่าเท่ากันหรือไม่
const (
Sunday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
const (
Morning = iota
Afternoon
Night
)
func main() {
// สิ่งที่ต้องการ มันต้องไม่เป็น true
fmt.Println(Sunday == Morning) // true
}
เราสามารถแก้ปัญหานี้ได้โดยการสร้าง type ใหม่ขึ้นมา เพื่อใช้เป็น enum type
type Day int64
const (
Sunday Day = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
type DayTime int64
const (
Morning DayTime = iota
Afternoon
Night
)
func main() {
// จะทำให้เราไม่สามารถเอามาเปรียบเทียบกันได้แล้ว
fmt.Println(Sunday == Morning)
// invalid operation: Sunday == Morning (mismatched types Day and DayTime)
}
อีกปัญหาหนึ่งก็คือ เมื่อเราสั่ง print ค่าของ enum ออกมามันจะเป็นตัวเลข ทำให้อ่านแล้วไม่เข้าใจความหมาย เช่น
type Day int64
const (
Sunday Day = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
func printDay(d Day) {
fmt.Println(d)
}
func main() {
printDay(Sunday) // 0
}
เพื่อแก้ปัญหานี้ ให้เพิ่ม receiver function String()
ให้กับ type ที่สร้างขึ้นมาใหม่ ดังนี้
func (d Day) String() string {
switch d {
case Sunday:
return "sunday "
case Monday:
return "monday"
case Tuesday:
return "tuesday"
case Wednesday:
return "wednesday"
case Thursday:
return "thursday"
case Friday:
return "friday"
case Saturday:
return "saturday"
default:
return "unknown"
}
}
เมื่อลองรันโปรแกรมใหม่จะได้คำว่า sunday
ออกมาแทน
ปัญหาถัดมา เนื่อง type Day เป็น int64 ทำให้เราสามารถสร้างตัวแปรของ Day และกำหนดค่าที่มากกว่า 6 ได้ ซึ่งเมื่อสั่ง printDay จะได้ค่าเป็น unknown
func main() {
d := Day(10)
printDay(d) // unknown
}
ดังนั้น เราจึงควรมีการตรวจสอบด้วยว่าค่าที่กำหนดมานั้นถูกต้องหรือไม่ ดังนี้
func (d Day) isValid() bool {
switch d {
case Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday:
return true
default:
return false
}
}
func main() {
d := Day(10)
if ok := d.isValid(); !ok {
fmt.Println("Invalid value")
return
}
printDay(d)
}
// Invalid value
สามารถดูโค้ดทั้งหมดได้ที่นี่