สารบัญ
- ทำไมต้อง Go
- ติดตั้ง (mise + VS Code)
- Go modules
- โครงสร้างโปรแกรม
- go run / build / fmt / vet
- ตัวแปร
- Type
- fmt verbs
- กับดัก Day 1
1 · ทำไมต้อง Go
| ภาษา | จุดขาย |
|---|---|
| C++ | Control, Hardware |
| Python | Productivity, Fast iteration |
| Java | Portability, Managed runtime |
| Go | Engineering Scale, Cloud & Concurrency |
ประวัติ: เกิดที่ Google ปี 2007 โดย Robert Griesemer, Rob Pike, Ken Thompson ต้องการภาษาที่ได้ครบ 3 อย่างพร้อมกัน — compile เร็ว · รันเร็ว · เขียนง่าย หาภาษาที่มีครบไม่เจอ เลยสร้างเอง
Go หรือ Golang? ชื่อทางการคือ Go —
ที่เรียก Golang เพราะตอนจดโดเมนใช้ go เฉย ๆ ไม่ได้
เลยใช้ golang.org (ปัจจุบันย้ายมา go.dev แล้ว)
Less is Exponentially More — 25 keywords ทั้งภาษา
เทียบกับ Java (~50) หรือ C++ (~90) — น้อยกว่า = จำน้อยกว่า =
โค้ดของทุกคนหน้าตาเหมือนกัน และเป็นเหตุผลที่ AI generate โค้ด Go
ได้แม่นกว่าภาษาอื่น (syntax เล็ก, static type, go fmt บังคับ style)
Performance (TechEmpower, PostgreSQL raw)
Go อยู่ตรงไหนของโลกจริง
| หมวด | เครื่องมือที่เขียนด้วย Go |
|---|---|
| Container & Orchestration | Docker, Kubernetes |
| Monitoring & Logging | Prometheus, Grafana Loki |
| IaC & Secrets | Terraform, Vault, Consul |
| Service Mesh & Network | Istio, Traefik |
| GitOps | ArgoCD |
| Storage | MinIO |
บริษัทที่ใช้: Google, Meta, Microsoft, Netflix, Uber, PayPal, Cloudflare, Dropbox, Twitch, Grab, LINE, Agoda, ByteDance, Monzo, American Express
2 · ติดตั้ง
VS Code
ลง extension ชื่อ Go (id: golang.go, publisher: Go Team at Google)
mise — จัดการเวอร์ชัน Go
# ติดตั้ง mise (Linux / macOS / WSL)
curl https://mise.run | sh
mise --version
# เปิดใช้งานใน shell
echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc # zsh
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc # bash
# ตั้ง Go เป็น global
mise use --global go@1.26
go version
# หรือกำหนดเฉพาะโปรเจกต์ (สร้างไฟล์ mise.toml)
mise use go@1.26
# รันโดยไม่ต้องติดตั้งถาวร
mise exec go@1.26 -- go version
# mise.toml
[tools]
go = "1.26.4"
ประโยชน์: คนละโปรเจกต์ใช้ Go คนละเวอร์ชันได้
และเพื่อนร่วมทีมได้เวอร์ชันเดียวกันอัตโนมัติเพราะ mise.toml อยู่ใน repo
3 · Go modules
mkdir go-to-hero && cd go-to-hero
go mod init go-to-hero # ชื่อสั้น
go mod init gitlab.com/username/go-to-hero # ชื่อเต็ม (ถ้าจะเผยแพร่)
go mod tidy # เพิ่มของที่ใช้ + ลบของที่ไม่ใช้ ← รันบ่อย ๆ
Module = ชุดของ package ที่ release/version/distribute ไปด้วยกัน
4 · โครงสร้างโปรแกรม
package main // ชื่อ main = executable / ชื่ออื่น = library
import (
"fmt"
"math/rand" // เรียกใช้ด้วย rand.Intn() ← ชิ้นสุดท้ายของ path
)
func init() { ... } // รันก่อน main เสมอ · มีหลายตัวได้ · เรียกเองไม่ได้
func main() { ... } // จุดเริ่มต้น · ไม่รับ param ไม่คืนค่า · มีตัวเดียว
ลำดับการทำงาน
5 · เครื่องมือ
| คำสั่ง | ทำอะไร |
|---|---|
go run . | compile ชั่วคราว → รัน → ลบทิ้ง (ตอนพัฒนา) |
go build | compile เป็น binary เก็บไว้ (ตอน deploy) |
go fmt ./... | จัดรูปแบบโค้ดให้เป็นมาตรฐานเดียวกันทั้งโลก |
go vet ./... | หาโค้ดที่ compile ผ่านแต่น่าจะผิด |
go mod tidy | จัดระเบียบ dependency |
go build -gcflags="-m" | ดูว่าตัวแปรไหน escape ไป heap |
Cross-compilation — จุดขายใหญ่ของ Go
GOOS=linux GOARCH=amd64 go build -o bin/app
| GOOS | GOARCH |
|---|---|
| windows · darwin (macOS) · linux · freebsd · android · ios · js (WebAssembly) | amd64 (64-bit x86) · 386 (32-bit x86) · arm64 · arm · riscv64 · wasm |
ได้ไฟล์เดียวจบ ไม่ต้องลง runtime ที่ปลายทาง — เหตุผลที่ Go ครองโลก DevOps
6 · ตัวแปร
var i int // zero value → 0
var j int = 2
var c, python, java = true, false, "no!"
k := 3 // ในฟังก์ชันเท่านั้น!
name, age := "Alice", 30
| สถานการณ์ | ใช้ |
|---|---|
| ในฟังก์ชัน มีค่าเริ่มต้น | := ← สำนวนมาตรฐาน |
| ต้องการ zero value | var x int |
| นอกฟังก์ชัน (package level) | var เท่านั้น |
| อยากบังคับ type ให้ชัด | var x float64 = 3 |
Zero values
| Type | Zero value |
|---|---|
| ตัวเลขทุกชนิด | 0 |
bool | false |
string | "" (ไม่ใช่ nil — string เป็น nil ไม่ได้) |
| pointer, slice, map, func, chan, interface | nil |
Go ไม่มี undefined — ตัวแปรพร้อมใช้เสมอ ไม่ต้องเช็ค null ก่อน
7 · Type
bool
string
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
byte // = uint8
rune // = int32 — Unicode code point (ตัวอักษร 1 ตัว)
float32 float64
complex64 complex128
ใช้ int กับ float64 จนกว่าจะมีเหตุผลเฉพาะ
| Type | ช่วง | ใช้ตอน |
|---|---|---|
int8 | −128 ถึง 127 | protocol, binary data |
int32 | ±2.1 พันล้าน | fixed-size field, Unicode rune |
int64 | ±9.22e18 | timestamp, database ID, file size |
uint | 0 ขึ้นไป | count/index เฉพาะกรณีที่ต้อง unsigned |
uint8 | 0 ถึง 255 | byte data, color channel, raw binary |
Type conversion — T(v)
i := 42
f := float64(i)
u := uint(f)
var x, y int = 3, 4
var dist float64 = math.Sqrt(float64(x*x + y*y))
Go ไม่แปลง type ให้อัตโนมัติ — int + float64 = compile error
Type inference — default type ของค่าคงที่
n := 42 // int (ไม่ใช่ int64)
f := 3.142 // float64 (ไม่ใช่ float32)
s := "hi" // string
b := true // bool
8 · fmt verbs ที่ใช้บ่อย
| verb | พิมพ์ | ตัวอย่าง |
|---|---|---|
%v | ค่าแบบ default | {Alice 30} |
%+v | ค่า + ชื่อ field | {Name:Alice Age:30} |
%T | type — เครื่องมือดีบักอันดับ 1 | main.User |
%d | จำนวนเต็ม | 42 |
%s | สตริง | hi |
%q | สตริงพร้อม quote | "hi" |
%t | bool | true |
%.2f | ทศนิยม 2 ตำแหน่ง | 2500.00 |
%% | เครื่องหมาย % จริง ๆ | % |
9 · กับดัก Day 1
| เขียน | คิดว่า | เกิดจริง |
|---|---|---|
import "os" แล้วไม่ใช้ | แค่ warning | 💥 compile error "os" imported and not used |
| ประกาศตัวแปรแล้วไม่ใช้ | ไม่เป็นไร | 💥 declared and not used |
count := 0 นอกฟังก์ชัน | ได้เหมือนในฟังก์ชัน | 💥 non-declaration statement outside function body |
i + f (int + float64) | Go แปลงให้ | 💥 mismatched types → ต้อง float64(i) + f |
a / b เมื่อทั้งคู่เป็น int | ได้ทศนิยม | 5/2 = 2 ตัดเศษทิ้ง → แปลงเป็น float64 ก่อนหาร |
int(f) เมื่อ f = 3.9 | ปัดเป็น 4 | 3 — ตัดทิ้ง ไม่ปัด |
uint8(big) เมื่อ big = 300 | error หรือ 255 | 44 — ล้นแล้ววนกลับเงียบ ๆ |
int(3.9) ใส่ค่าคงที่ตรง ๆ | เหมือนผ่านตัวแปร | 💥 compile error — constant Go ตรวจได้ตั้งแต่ compile time |
len("สวัสดี") | ได้ 6 | 18 — นับ bytes → ใช้ len([]rune(s)) |