เรียนรู้การใช้ _ struct{} เพื่อป้องกันการสร้าง Struct Literals แบบไม่ระบุ key fields ในภาษา Go
สมมติเรามี struct ชื่อ Person ดังต่อไปนี้
1type Person struct {2 Name string3 Age uint4 Gender string5}
แน่นอนว่า struct ดังกล่าวสามารถใช้เพื่อสร้าง Struct Literals ได้สองรูปแบบ รูปแบบแรกประกอบด้วย keyed fields ในขณะที่รูปแบบที่สองระบุ fields แบบ unkeyed fields
1// keyed fields2Person{Name: "Somchai", Age: 24, Gender: "Male"}34// unkeyed fields5Person{"Somchai", 24, "Male"}
สำหรับรูปแบบที่สองนั้นหาก struct Person ของเราเพิ่ม field ใหม่ โค้ดส่วนนี้จะเกิดข้อผิดพลาด ในขณะที่ struct literal แบบแรกจะไม่เกิดข้อผิดพลาดในการประกาศใด ๆ นอกจากนี้ถ้า struct Person ของเรามีฟิลด์จำนวนมาก รูปแบบการประกาศที่สองจะทำความเข้าใจยาก นั่นเพราะเมื่อปริมาณฟิลด์มีมากจะไม่สามารถสื่อความได้อย่างชัดเจนว่าแต่ละช่องของฟิลด์ที่ส่งไปยัง struct literal นั้นคือค่าใดบ้าง
เรามีทริคสำหรับป้องกันการสร้าง struct literal ในรูปแบบที่สอง
กล่าวคือทริคนี้จะทำให้เราต้องระบุค่า key ทุกครั้งเมื่อทำการประกาศ struct literal
ความสามารถนี้จะเกิดขึ้นได้เมื่อเราทำการเพิ่มฟิลด์ใหม่คือ _ struct{}
1type Person struct {2 _ struct{}3 Name string4 Age uint5 Gender string6}
เราทำการเพิ่ม Blank Identifier (_
) เป็นชื่อฟิลด์ด้วยชนิดข้อมูลคือ Empty Struct Type (struct{}
)
ในภาษา Go นั้นเราไม่สามารถประกาศ Struct Literals ด้วยการใส่ key ในบาง fields แล้วละบาง fields ด้วยการไม่ใส่ key ได้
1// error: mixture of field:value and value elements in struct literal2Person{Name: "Somchai", 24, "Male"}
เมื่อเราระบุฟิลด์คือ _ struct{}
เป็นฟิลด์แรกนั่นแปลว่าหากเราใช้รูปแบบที่ 2
เราจะต้องระบุค่าลง struct literals ด้วย struct{}{}
ในช่องแรกด้วยเท่านั้น
1// cannot use "Somchai" (untyped string constant) as struct{} value in struct literal2Person{"Somchai", 24, "Male"}34// ไม่ error5Person{struct{}{}, "Somchai", 24, "Male"}
แน่นอนว่าการระบุ struct{}{}
เป็นช่องแรกไม่ใช่วิธีทั่วไปที่เราทำกันอยู่แล้ว
ดังนั้นโดยทางปฏิบัติแล้วจึงเหลือวิธีที่เหมาะสมในการใช้งานคือการสร้าง Struct Literals ด้วย keyed fields เท่านั้น
1Person{Name: "Somchai", Age: 24, Gender: "Male"}
วิธีการใช้ _ struct{}
นี้ไม่ใช่วิธีปฏิบัตทั่วไปหรือ Best Practice แต่อย่างใด
หากแต่เป็นทริคสำหรับการป้องกันไม่ให้สร้าง Struct Literals ด้วยการไม่ใส่ keyed fields เท่านั้น