Go: วิธีป้องกันการสร้าง Struct Literals แบบไม่ระบุ key fields
Nuttavut Thongjor
Go

เรียนรู้การใช้ _ struct{} เพื่อป้องกันการสร้าง Struct Literals แบบไม่ระบุ key fields ในภาษา Go

คำอธิบาย
ความคิดเห็น

สมมติเรามี struct ชื่อ Person ดังต่อไปนี้

Go
1type Person struct {
2 Name string
3 Age uint
4 Gender string
5}

แน่นอนว่า struct ดังกล่าวสามารถใช้เพื่อสร้าง Struct Literals ได้สองรูปแบบ รูปแบบแรกประกอบด้วย keyed fields ในขณะที่รูปแบบที่สองระบุ fields แบบ unkeyed fields

Go
1// keyed fields
2Person{Name: "Somchai", Age: 24, Gender: "Male"}
3
4// unkeyed fields
5Person{"Somchai", 24, "Male"}

สำหรับรูปแบบที่สองนั้นหาก struct Person ของเราเพิ่ม field ใหม่ โค้ดส่วนนี้จะเกิดข้อผิดพลาด ในขณะที่ struct literal แบบแรกจะไม่เกิดข้อผิดพลาดในการประกาศใด ๆ นอกจากนี้ถ้า struct Person ของเรามีฟิลด์จำนวนมาก รูปแบบการประกาศที่สองจะทำความเข้าใจยาก นั่นเพราะเมื่อปริมาณฟิลด์มีมากจะไม่สามารถสื่อความได้อย่างชัดเจนว่าแต่ละช่องของฟิลด์ที่ส่งไปยัง struct literal นั้นคือค่าใดบ้าง

เรามีทริคสำหรับป้องกันการสร้าง struct literal ในรูปแบบที่สอง กล่าวคือทริคนี้จะทำให้เราต้องระบุค่า key ทุกครั้งเมื่อทำการประกาศ struct literal ความสามารถนี้จะเกิดขึ้นได้เมื่อเราทำการเพิ่มฟิลด์ใหม่คือ _ struct{}

Go
1type Person struct {
2 _ struct{}
3 Name string
4 Age uint
5 Gender string
6}

เราทำการเพิ่ม Blank Identifier (_) เป็นชื่อฟิลด์ด้วยชนิดข้อมูลคือ Empty Struct Type (struct{}) ในภาษา Go นั้นเราไม่สามารถประกาศ Struct Literals ด้วยการใส่ key ในบาง fields แล้วละบาง fields ด้วยการไม่ใส่ key ได้

Go
1// error: mixture of field:value and value elements in struct literal
2Person{Name: "Somchai", 24, "Male"}

เมื่อเราระบุฟิลด์คือ _ struct{} เป็นฟิลด์แรกนั่นแปลว่าหากเราใช้รูปแบบที่ 2 เราจะต้องระบุค่าลง struct literals ด้วย struct{}{} ในช่องแรกด้วยเท่านั้น

Go
1// cannot use "Somchai" (untyped string constant) as struct{} value in struct literal
2Person{"Somchai", 24, "Male"}
3
4// ไม่ error
5Person{struct{}{}, "Somchai", 24, "Male"}

แน่นอนว่าการระบุ struct{}{} เป็นช่องแรกไม่ใช่วิธีทั่วไปที่เราทำกันอยู่แล้ว ดังนั้นโดยทางปฏิบัติแล้วจึงเหลือวิธีที่เหมาะสมในการใช้งานคือการสร้าง Struct Literals ด้วย keyed fields เท่านั้น

Go
1Person{Name: "Somchai", Age: 24, Gender: "Male"}

วิธีการใช้ _ struct{} นี้ไม่ใช่วิธีปฏิบัตทั่วไปหรือ Best Practice แต่อย่างใด หากแต่เป็นทริคสำหรับการป้องกันไม่ให้สร้าง Struct Literals ด้วยการไม่ใส่ keyed fields เท่านั้น