เน้นพื้นฐานที่ใช้จริง: ตัวแปร ฟังก์ชัน struct/interface, concurrency และแนวทาง best practice สำหรับงาน backend
Go (Golang) เด่นเรื่อง performance, concurrency (goroutine), เหมาะกับงาน backend, API, microservices
ในงานจริงจะใช้ fmt และ bufio สำหรับอ่านค่าจาก stdin และพิมพ์ผลลัพธ์อย่างปลอดภัย
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter name: ")
name, _ := reader.ReadString('
')
fmt.Println("Hello", name)
}package main
import "fmt"
func main() {
var age int = 20
name := "Somchai"
isStudent := true
fmt.Println(name, age, isStudent)
}package main
import "fmt"
func add(a int, b int) int {
return a + b
}
func main() {
fmt.Println(add(2, 3))
}Go มี if/else, switch, for แบบเดียว (ไม่มี while) และนิยมใช้ short statement ใน if เพื่อประกาศตัวแปรชั่วคราว
package main
import "fmt"
func main() {
score := 85
if score >= 80 {
fmt.Println("A")
} else if score >= 70 {
fmt.Println("B")
} else {
fmt.Println("C")
}
for i := 1; i <= 3; i++ {
fmt.Println("loop", i)
}
// switch แบบไม่มี break
day := "Mon"
switch day {
case "Mon", "Tue":
fmt.Println("weekday")
default:
fmt.Println("weekend")
}
}Slice เป็นโครงสร้างสำคัญใน Go: มี length/capacity และอาจแชร์ backing array กันได้ เทคนิคที่ใช้จริงคือการ copy ก่อนแก้ เพื่อกัน side-effect
package main
import "fmt"
func main() {
a := []int{1, 2, 3}
b := append([]int{}, a...) // copy
b[0] = 99
fmt.Println(a) // [1 2 3]
fmt.Println(b) // [99 2 3]
}Map ใช้เก็บ key/value แต่ควรระวัง: map ไม่ thread-safe (ถ้ามี goroutine หลายตัวเขียนพร้อมกันต้องมี mutex)
package main
import "fmt"
func main() {
m := map[string]int{"a": 1}
m["b"] = 2
if v, ok := m["c"]; ok {
fmt.Println(v)
} else {
fmt.Println("not found")
}
}Receiver แบบ value จะ copy ค่า ส่วน pointer receiver จะปรับค่าใน struct ได้จริงและประหยัดการ copy ใน struct ใหญ่
package main
import "fmt"
type Counter struct{ Value int }
func (c *Counter) Inc() {
c.Value += 1
}
func main() {
c := Counter{Value: 0}
c.Inc()
fmt.Println(c.Value)
}Go ใช้ modules เพื่อจัดการ dependency (go.mod) แนวทางที่ดีคือแยก package ตามหน้าที่และไม่ export สิ่งที่ไม่จำเป็น
// go.mod (ตัวอย่าง) // module github.com/yourname/project // go 1.22
Table-driven tests เป็นรูปแบบยอดนิยมใน Go: เขียน test case หลาย ๆ เคสใน slice แล้ววนลูปทดสอบ
// add_test.go
package main
import "testing"
func add(a, b int) int { return a + b }
func TestAdd(t *testing.T) {
cases := []struct {
a, b int
want int
}{
{1, 2, 3},
{0, 0, 0},
{-1, 1, 0},
}
for _, c := range cases {
got := add(c.a, c.b)
if got != c.want {
t.Fatalf("add(%d,%d)=%d want %d", c.a, c.b, got, c.want)
}
}
}