Skip to main content

Golang 語法速查(一)

1. 基礎結構 (Basic Structure)

package main // 定義包名

import "fmt" // 導入包

// 主函數,程式入口
func main() {
fmt.Println("Hello, World!")
}

2. 變數與常數 (Variables & Constants)

變數宣告

var a int = 10         // 標準宣告
var b = 20 // 推導類型
c := 30 // 簡短宣告 (只能在函數內使用)
var d, e int = 40, 50 // 多變數宣告

常數

const Pi = 3.14
const (
StatusOk = 200
StatusNotFound = 404
)

3. 資料型態 (Data Types)

基本型態

  • bool: true, false
  • string: "hello"
  • int, int8, int16, int32, int64
  • uint, uint8, uint16, uint32, uint64
  • byte (uint8 的別名)
  • rune (int32 的別名,代表 Unicode 碼點)
  • float32, float64
  • complex64, complex128

陣列 (Arrays) & 切片 (Slices)

// Array: 固定長度
var arr [5]int
arr2 := [3]int{1, 2, 3}

// Slice: 動態長度
var s []int // nil slice
s2 := []int{1, 2, 3} // slice literal
s3 := make([]int, 5, 10) // make(type, len, cap)

s2 = append(s2, 4) // 追加元素
sub := s2[1:3] // 切片操作 [start:end] (不包含 end)

映射 (Maps)

m := make(map[string]int)
m["one"] = 1
val, ok := m["one"] // 檢查 key 是否存在
delete(m, "one") // 刪除 key

4. 流程控制 (Control Flow)

If-Else

if x > 0 {
fmt.Println("Positive")
} else if x < 0 {
fmt.Println("Negative")
} else {
fmt.Println("Zero")
}

// 帶初始化的 if
if val := compute(); val > 10 {
fmt.Println(val)
}

For Loop (Go 只有 for 迴圈)

// 標準 for
for i := 0; i < 5; i++ {
fmt.Println(i)
}

// 類似 while
j := 0
for j < 5 {
j++
}

// 無窮迴圈
for {
break // 跳出
}

// Range (遍歷 slice, map, string)
for index, value := range s2 {
fmt.Printf("%d: %d\n", index, value)
}

Switch

switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X")
case "linux":
fmt.Println("Linux")
default:
fmt.Println("Other")
}

5. 函數 (Functions)

func add(x int, y int) int {
return x + y
}

// 多返回值
func swap(x, y string) (string, string) {
return y, x
}

// 命名返回值
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return // 自動返回 x, y
}

6. 指針 (Pointers)

i := 42
p := &i // p 指向 i
fmt.Println(*p) // 讀取 p 指向的值
*p = 21 // 設定 p 指向的值

7. 結構體 (Structs) & 方法 (Methods)

結構體是將多個欄位組合成一個型別的複合型別,類似其他語言裡的「類」的資料部分(不含繼承)。用 type 名稱 struct { 欄位... } 定義,欄位用大寫開頭表示可匯出(package 外可存取)。

建立時可用 Vertex{1, 2} 依欄位順序給值,或用 v.Xv.Y 讀寫欄位。

方法是綁在型別上的函式,寫法為 func (接收者) 方法名(參數) 回傳型別。接收者分兩種:

  • 值接收者 (v Vertex):傳入的是副本,方法內對欄位的修改不會影響呼叫端的變數;適合只讀、不變的邏輯(例如計算)。
  • 指針接收者 (v *Vertex):傳入的是指標,方法內可修改原結構體的欄位;適合會改變狀態的操作(例如縮放、設定)。

呼叫時 Go 會自動處理:有指標時會自動解參考((*p).Scale(2) 可寫成 p.Scale(2)),有值時也會自動取址(若方法要的是指標接收者)。同一型別上不要混用值/指標接收者做同一類操作,以免語意混亂。

type Vertex struct {
X int
Y int
}

v := Vertex{1, 2}
v.X = 4

// 方法:值接收者,只讀計算,不修改 v
func (v Vertex) Abs() float64 {
return math.Sqrt(float64(v.X*v.X + v.Y*v.Y))
}

// 指針接收者:可修改 struct 內容
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}

8. 介面 (Interfaces)

type Abser interface {
Abs() float64
}

// 只要類型實現了介面中的所有方法,即視為實現了該介面 (隱式實現)