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, falsestring: "hello"int,int8,int16,int32,int64uint,uint8,uint16,uint32,uint64byte(uint8 的別名)rune(int32 的別名,代表 Unicode 碼點)float32,float64complex64,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.X、v.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
}
// 只要類型實現了介面中的所有方法,即視為實現了該介面 (隱式實現)