Go Style Guide (คู่มือสไตล์ Go)
หมายเหตุ: เอกสารนี้เป็นส่วนหนึ่งของชุดเอกสาร Go Style ของ Google ถือเป็น เกณฑ์ปฏิบัติ (Normative) และ มาตรฐานถาวร (Canonical) ที่ต้องปฏิบัติตาม
หลักการของสไตล์ (Style Principles)
หลักการสำคัญในการเขียนโค้ด Go ให้อ่านง่าย เรียงตามลำดับความสำคัญจากมากไปน้อย มีดังนี้:
- ความชัดเจน (Clarity): ผู้อ่านต้องเข้าใจจุดประสงค์และเหตุผลของโค้ดได้อย่างชัดเจน
- ความเรียบง่าย (Simplicity): โค้ดควรบรรลุเป้าหมายด้วยวิธีที่ง่ายที่สุดเท่าที่จะเป็นไปได้
- ความกระชับ (Concision): โค้ดควรมีเนื้อหาสาระมากและมีส่วนรบกวนน้อย (High signal-to-noise ratio)
- การดูแลรักษา (Maintainability): โค้ดต้องเขียนให้ดูแลรักษาและแก้ไขได้ง่าย
- ความสม่ำเสมอ (Consistency): โค้ดควรสอดคล้องกับมาตรฐานของ Codebase โดยรวม
1. ความชัดเจน (Clarity)
หัวใจสำคัญคือการเขียนเพื่อให้ ผู้อ่าน เข้าใจ ไม่ใช่เพื่อให้ผู้เขียนเขียนง่าย ความชัดเจนแบ่งเป็น 2 ส่วน:
- โค้ดกำลังทำอะไร? (What): ควรทำให้ชัดเจนด้วยการตั้งชื่อตัวแปรที่ดี, การเว้นวรรค, และการแบ่งฟังก์ชัน
- ทำไมถึงทำแบบนั้น? (Why): คอมเมนต์ควรเน้นอธิบายเหตุผล (Rationale) โดยเฉพาะเมื่อมีตรรกะที่ซับซ้อน หรือข้อยกเว้นทางธุรกิจ อย่าเขียนคอมเมนต์ที่แค่อธิบายสิ่งที่โค้ดบอกอยู่แล้ว
2. ความเรียบง่าย (Simplicity)
โค้ดที่เรียบง่ายคือโค้ดที่อ่านจากบนลงล่างได้เข้าใจง่าย ไม่ซ่อนกลไก หรือมีการสร้าง Abstraction ที่ไม่จำเป็น
กลไกที่น้อยที่สุด (Least mechanism)
หากมีหลายวิธีในการทำสิ่งเดียวกัน ให้เลือกวิธีที่ใช้เครื่องมือพื้นฐานที่สุดก่อน:
- ใช้โครงสร้างภาษาหลัก (Slice, Map, Channel, Loop)
- หากไม่พอ ให้ใช้ Standard Library
- พิจารณา Library ขององค์กร ก่อนจะนำเข้า Dependency ภายนอกใหม่ๆ
3. ความกระชับ (Concision)
เน้นเนื้อหา ลดสิ่งรบกวน เช่น โค้ดที่ซ้ำซ้อน หรือ Syntax ที่เกินจำเป็น
- ตัวอย่าง: ใช้ Table-driven testing เพื่อลดโค้ดซ้ำซ้อนในการทดสอบ
- Signal Boosting: หากโค้ดดูคล้ายกันมากแต่มีจุดต่างสำคัญ (เช่น
err == nil แทนที่จะเป็น != nil) ควรใส่คอมเมนต์เพื่อดึงดูดความสนใจ
4. การดูแลรักษา (Maintainability)
โค้ดถูกแก้ไขบ่อยกว่าถูกเขียนใหม่ โค้ดที่ดูแลง่ายต้อง:
- เติบโตได้ง่าย (APIs structured gracefully)
- ชัดเจนเรื่องการตั้งสมมติฐาน
- หลีกเลี่ยงการซ่อน Logic สำคัญไว้ในบรรทัดเดียวที่อ่านยาก (เช่น การ Assign ค่าพร้อมเช็ค Error ในบรรทัดเดียวที่ซับซ้อนเกินไป)
- การตั้งชื่อที่คาดเดาได้: พารามิเตอร์และ Receiver ที่ทำหน้าที่เหมือนกัน ควรชื่อเหมือนกัน
5. ความสม่ำเสมอ (Consistency)
ความสม่ำเสมอภายในแพ็กเกจเดียวกันสำคัญที่สุด อย่างไรก็ตาม ความสม่ำเสมอไม่ควรถูกใช้เพื่อลบล้างหลักการข้ออื่น (เช่น ความชัดเจน)
แนวทางปฏิบัติหลัก (Core guidelines)
กฎเหล่านี้คือสิ่งที่โค้ด Go ทั้งหมดต้องปฏิบัติตาม:
- ไฟล์ Go ทั้งหมดต้องจัดรูปแบบด้วย
gofmt
การใช้ตัวพิมพ์ (MixedCaps)
- Go ใช้
MixedCaps (CamelCase) เสมอ ไม่ใช้ snake_case (ขีดล่าง)
- กฎนี้รวมถึงค่าคงที่ (Constant) ด้วย เช่นใช้
MaxLength ไม่ใช่ MAX_LENGTH
- ตัวแปร Local ถือเป็น unexported (ขึ้นต้นตัวเล็ก)
ความยาวบรรทัด (Line length)
- ไม่มีข้อกำหนดความยาวตายตัว
- ถ้าบรรทัดยาวเกินไป ให้แก้ด้วยการ Refactor โค้ดใหม่ ไม่ใช่แค่เคาะบรรทัดลงมา
- ห้ามตัดบรรทัดก่อนการเปลี่ยน Indent (เช่น หน้า declaration) หรือตัดกลาง String (เช่น URL) เพียงเพื่อให้สั้นลง
การตั้งชื่อ (Naming)
- ชื่อใน Go มักจะสั้นกว่าภาษาอื่น แต่ยังคงต้องชัดเจน
- ชื่อไม่ควรซ้ำซ้อนกับบริบทที่รู้อยู่แล้ว (เช่น แพ็กเกจชื่อ
user ฟังก์ชันไม่ต้องชื่อ GetUserInfo แค่ Get ก็พอ)
ความสม่ำเสมอเฉพาะที่ (Local consistency)
- หากคู่มือไม่ได้ระบุไว้ ให้ดูโค้ดรอบข้าง (ในไฟล์หรือแพ็กเกจเดียวกัน) ว่าเขาทำกันอย่างไร แล้วทำตามนั้น
- ตัวอย่างที่ยอมรับได้: การเลือกใช้
%s หรือ %v ในการ print error
- แต่ถ้ารูปแบบเดิมแย่หรือขัดแย้งกับหลักการหลัก อย่าทำตาม ให้ถือโอกาส Refactor ให้ถูกต้อง