กลับไปหน้าบทความ

🦫 Go สำหรับ Backend (ครบระดับ)

เน้นพื้นฐานที่ใช้จริง: ตัวแปร ฟังก์ชัน struct/interface, concurrency และแนวทาง best practice สำหรับงาน backend

📋 เนื้อหา (พื้นฐาน)

  • 🧭 Go คืออะไร เหมาะกับงานไหน
  • 🔤 Variables & Types
  • 🧩 Functions
  • 🧮 Control Flow & Loops
  • 🎮 ตัวอย่าง (จำลองผลลัพธ์)
  • 🏁 สรุป (พื้นฐาน)
  • 📝 แบบฝึกหัด (พื้นฐาน)

🧭 Go คืออะไร เหมาะกับงานไหน

Go (Golang) เด่นเรื่อง performance, concurrency (goroutine), เหมาะกับงาน backend, API, microservices

🧾 Input/Output เบื้องต้น

ในงานจริงจะใช้ 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)
}

🔤 Variables & Types

package main

import "fmt"

func main() {
  var age int = 20
  name := "Somchai"
  isStudent := true

  fmt.Println(name, age, isStudent)
}

🧩 Functions

package main

import "fmt"

func add(a int, b int) int {
  return a + b
}

func main() {
  fmt.Println(add(2, 3))
}

🧮 Control Flow & Loops

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/Map เชิงลึก

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")
  }
}

🧰 Methods & Receivers

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)
}

📦 Package/Module (แนวคิด)

Go ใช้ modules เพื่อจัดการ dependency (go.mod) แนวทางที่ดีคือแยก package ตามหน้าที่และไม่ export สิ่งที่ไม่จำเป็น

// go.mod (ตัวอย่าง)
// module github.com/yourname/project
// go 1.22

🧪 Testing ระดับกลาง

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)
    }
  }
}

🎮 ตัวอย่าง (จำลองผลลัพธ์)

🏁 สรุป (พื้นฐาน)

  • ✅ Go เหมาะกับงาน backend และระบบที่ต้องการความเร็ว
  • ✅ ประกาศตัวแปรได้ทั้ง var และ :=
  • ✅ ฟังก์ชันใน Go เน้น type ชัด และอ่านง่าย

📝 แบบฝึกหัด (พื้นฐาน)

  1. เขียนโปรแกรมรับค่า a,b แล้วพิมพ์ผลบวก
  2. สร้าง slice เก็บคะแนน แล้ววนลูปหาค่าเฉลี่ย
  3. เขียนฟังก์ชัน isPassing(score, passingScore) คืนค่า bool