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(複數)
info

複數用來表示「實部 + 虛部」。complex64 的實部與虛部各是 float32(共 64 bit),complex128 各是 float64(共 128 bit)。寫法有字面量 1+2i,或函式 complex(實部, 虛部);real、imag 分別取出實部與虛部。日常後端很少用到,多見於科學計算、訊號處理與傅立葉轉換。

var a complex64 = 1 + 2i
b := complex(3.0, 4.0) // 預設是 complex128

real(b) // 3.0,實部
imag(b) // 4.0,虛部

陣列 (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
}
info

Vertex{1, 2} 得到的是結構體的值,型別是 Vertex。字面值前加上 & 會取得指標,型別是 *Vertex,結果與先 new(Vertex) 再賦值欄位相同。new 只配置零值並回傳指標,不會接收 1, 2;欄位由後面的賦值,或由 &Vertex{1, 2} 一次寫入。

TypeScript 的 new Vertex(1, 2) 對得上的是帶 & 的寫法:都會得到一個參考,而且欄位已經是 1 和 2。Go 沒有建構函式,數字是字面值賦值;TypeScript 的 new 會呼叫 constructor 把參數寫進欄位。

type Vertex struct {
X int
Y int
}

val := Vertex{1, 2} // 型別 Vertex
ptr := &Vertex{1, 2} // 型別 *Vertex

// 與上一行相同
p := new(Vertex) // 欄位先是 0, 0
p.X = 1
p.Y = 2
class Vertex {
x: number
y: number
constructor(x: number, y: number) {
this.x = x
this.y = y
}
}

const v = new Vertex(1, 2) // 對應 Go 的 &Vertex{1, 2}

8. 介面 (Interfaces)​

type Abser interface {
Abs() float64
}

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