ข้ามไปยังเนื้อหา

Types & Data

ทุกค่าใน Go มี type แบบ static ที่กำหนดตั้งแต่ compile time ซึ่ง Go แบ่ง type ออกเป็นสองกลุ่มหลัก:

Value types — ตัวแปรเก็บข้อมูลโดยตรง การ assign ค่าจะ copy ข้อมูลทั้งหมด ได้แก่ boolean, ตัวเลข (int, int64, float64, uint8, …), และ string รวมถึง composite value types อย่าง array และ struct

Reference-like types — ตัวแปรเก็บ header ขนาดเล็กที่ชี้ไปยังโครงสร้างข้อมูลจริงซึ่งถูก allocate ไว้ที่อื่น การ assign จะ copy แค่ header ดังนั้นตัวแปรสองตัวอาจชี้ไปข้อมูลชุดเดียวกันได้ ได้แก่ slice, map, channel, function, และ pointer

flowchart TD
  Root["Go Type Taxonomy"]
  Root --> Value["Value types (copy on assign)"]
  Root --> Ref["Reference-like (header copied)"]
  Value --> V1["bool, int, float64, string"]
  Value --> V2["[N]T (array)"]
  Value --> V3["struct { ... }"]
  Ref --> R1["*T (pointer)"]
  Ref --> R2["[]T (slice)"]
  Ref --> R3["map[K]V"]
  Ref --> R4["chan T, func(...)"]
Go types split into value types (copied on assign) and reference-like types (header copied)
บทเรียนหัวข้อ
หน้านี้ภาพรวม Type และโปรแกรมตัวอย่างแรก
Structsการนิยาม struct, embedding, การเปรียบเทียบ
SlicesArray vs slice, make, append, copy
Mapsmake(map[K]V), comma-ok, delete, การวน loop
Pointers& และ *, mutation, nil pointer

โปรแกรมด้านล่างนิยาม struct ชื่อ Point สร้าง slice []Point แล้วค้นหาชื่อจาก map[string]int ซึ่งแสดงให้เห็น value type (Point ถูก copy), slice literal, และการเข้าถึง map พร้อม zero-value เมื่อ key ไม่มีอยู่

package main
import "fmt"
type Point struct {
X, Y int
}
func main() {
// Struct literal with named fields
p := Point{X: 3, Y: 4}
fmt.Println(p.X, p.Y)
// Slice of structs
points := []Point{
{X: 0, Y: 0},
{X: 1, Y: 2},
{X: 3, Y: 4},
}
for _, pt := range points {
fmt.Printf("(%d, %d)\n", pt.X, pt.Y)
}
// Map: string -> int
score := map[string]int{
"Alice": 95,
"Bob": 87,
}
fmt.Println(score["Alice"])
fmt.Println(score["Charlie"]) // missing key -> zero value (0)
}
ประเภทประโยชน์ต้นทุน
value type (struct, array)predictable behavior, ไม่มี aliasingcopy cost สำหรับ type ขนาดใหญ่
reference-like type (slice, map)แชร์ data โดยไม่ต้อง copyshared mutation — goroutine หนึ่งแก้ไขอาจกระทบอีกตัว
static typingcompiler catch errors เร็วverbose type declarations
composite literalsreadable initializationsyntax แตกต่างกันตาม type
  • array และ slice คือสิ่งเดียวกัน — array มีขนาดคงที่เป็นส่วนของ type เช่น [3]int[4]int; slice เป็น dynamic view ของ array
  • map safe สำหรับ concurrent access — Go map ไม่ใช่ — ต้องใช้ sync.Mutex หรือ sync.RWMutex ถ้า goroutine หลายตัวอ่าน/เขียนพร้อมกัน
  • struct copy เสมอแพง — struct เล็ก (2-4 fields) copy เร็วมาก บางครั้งเร็วกว่าการใช้ pointer ที่ต้อง dereference และอาจ escape to heap

💡 ตัวอย่างจากของจริง

Kubernetes ใช้ slice สำหรับ pod list และ container list — แต่ละ reconcile loop สร้าง slice ใหม่ผ่าน append

Prometheus ใช้ map สำหรับ metric label — map[string]string เป็น label set หลัก

Docker ใช้ struct + pointer receiver สำหรับ container state management

อะไรคือ value type ใน Go — หมายความว่าการ assign จะ copy ข้อมูล?
Go จะ print อะไรเมื่อคุณอ่าน map key ที่ยังไม่เคยกำหนดค่า?
ทั้ง `[]Point` slice และ `[3]Point` array เก็บค่า Point ความแตกต่างหลักคืออะไร?