語法基礎

Go 語言基本語法:變數、常數、型別。

Hello World

package main

import "fmt"

func main() {
    fmt.Println("Hello World")
}

Variables

宣告方式

// 完整宣告
var name string = "Alice"

// 型別推斷
var age = 25

// 短宣告(僅限函式內)
count := 10

// 多變數宣告
var (
    x int    = 1
    y string = "hello"
    z bool   = true
)

// 同時賦值
a, b := 1, 2

零值

未初始化的變數會有零值:

型別零值
int, float640
string""
boolfalse
pointer, slice, map, channel, interfacenil

Constants

常數宣告與使用。

const Pi = 3.14159

const (
    StatusOK    = 200
    StatusError = 500
)

iota

自動遞增的常數生成器。

const (
    Sunday = iota // 0
    Monday        // 1
    Tuesday       // 2
    Wednesday     // 3
    Thursday      // 4
    Friday        // 5
    Saturday      // 6
)

iota 進階用法

// 位元遮罩
const (
    Read    = 1 << iota // 1
    Write               // 2
    Execute             // 4
)

// 跳過值
const (
    A = iota // 0
    _        // 跳過 1
    B        // 2
)

// 資料大小
const (
    _  = iota
    KB = 1 << (10 * iota) // 1024
    MB                    // 1048576
    GB                    // 1073741824
)

Base64 Encoding

Go 支援標準 Base64 編碼與 URL 安全編碼。

import "encoding/base64"

data := "Hello, World!"

// 標準編碼
encoded := base64.StdEncoding.EncodeToString([]byte(data))
// SGVsbG8sIFdvcmxkIQ==

decoded, _ := base64.StdEncoding.DecodeString(encoded)
// Hello, World!

// URL 安全編碼
urlEncoded := base64.URLEncoding.EncodeToString([]byte(data))

Type Assertions

型別斷言用於從 interface{} 取得具體型別。

var i interface{} = "hello"

// 基本斷言(失敗會 panic)
s := i.(string)
fmt.Println(s) // "hello"

// 安全斷言
s, ok := i.(string)
if ok {
    fmt.Println(s)
}

// 錯誤的斷言
n, ok := i.(int)
fmt.Println(n, ok) // 0, false

Type Switch

func describe(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("Integer: %d\n", v)
    case string:
        fmt.Printf("String: %s\n", v)
    case bool:
        fmt.Printf("Boolean: %t\n", v)
    default:
        fmt.Printf("Unknown type: %T\n", v)
    }
}

Generics

Go 1.18+ 支援

基本語法

func Min[T int | float64](a, b T) T {
    if a < b {
        return a
    }
    return b
}

// 使用
Min[int](1, 2)    // 1
Min(1.5, 2.5)     // 1.5(型別推斷)

comparable 類型

comparable 代表可以使用 ==!= 運算符進行比較的類型:

  1. 數值型別:int, int8, int16, int32, int64, uint…、float32, float64complex64, complex128
  2. string
  3. bool
  4. 所有指標類型
  5. channel
  6. interface
  7. Struct:僅當所有欄位都是 comparable type
  8. Array:僅當元素類型是 comparable type

不可 comparable 的類型

  1. Slice
  2. Map
  3. Function
  4. 包含上述不可比較類型欄位的結構體
// 可用作 map key
map[string]int     // OK
map[*string]int    // OK
map[[]string]int   // 編譯錯誤,slice 不可 comparable

Go Files

  • go.mod:模組定義
  • go.sum:依賴校驗(hash 確保依賴一致性)
  • go.work:工作區設定

JSON

Decoding & Encoding

import "encoding/json"

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

// Marshal (struct → JSON)
p := Person{Name: "Alice", Age: 30}
data, _ := json.Marshal(p)
// {"name":"Alice","age":30}

// Unmarshal (JSON → struct)
var p2 Person
json.Unmarshal([]byte(`{"name":"Bob","age":25}`), &p2)

omitempty

  • -:永遠排除該欄位
指定當欄位為空值(false, 0, nil pointer, nil interface, 空 array/slice/map/string)時,從編碼中省略該欄位。
type Person struct {
    Name    string `json:"name,omitempty"`
    Age     int    `json:"age,omitempty"`
    Address string `json:"-"`  // 永遠不會出現在 JSON 中
}

Time

  • Time Format: "2006-01-02 15:04:05.999999999 -0700 MST"
import "time"

now := time.Now()

// 格式化
formatted := now.Format("2006-01-02 15:04:05")

// 解析
t, _ := time.Parse("2006-01-02", "2024-01-15")

// 時間運算
tomorrow := now.Add(24 * time.Hour)
duration := tomorrow.Sub(now)

相關主題