Like Share Discussion Bookmark Smile

J.J. Huang   2025-01-03   Getting Started Golang 00.簡單介紹   瀏覽次數:次   DMCA.com Protection Status

Go | 我到底哪裡這麼特別?

💬簡介

Go(Golang)是由 Google 開發的編譯型、靜態強型別程式語言,擁有並行處理、垃圾回收等特性,旨在提供高效、安全的開發體驗。這裡介紹幾個讓 Go 與眾不同的關鍵特點。

圖片來源:MagicStudio產生。

🍰簡單語法

語法設計簡潔直觀,避免了 C 語言中的繁瑣細節。不使用複雜結構,像 ++-- 被簡化為語句,並限制指標運算,提高了安全性和可維護性。內建的切片和字典型別也使得開發更加簡單。

【範例】<點擊>
  • 簡單的變數宣告及流程控制
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package main

    import "fmt"

    func main() {
    // 宣告變數
    var name string = "Golang"
    var age int = 10

    // 輸出
    fmt.Println("Hello,", name)
    fmt.Println("Age:", age)

    // 判斷式
    if age > 5 {
    fmt.Println(name, "is older than 5.")
    }
    }

    📝這段程式碼展示了如何在 Go 中簡單地宣告變數、使用條件判斷及輸出結果。

  • 簡化的 ++-- 運算
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    package main

    import "fmt"

    func main() {
    var x int = 10
    x++ // 正確:++作為語句使用
    fmt.Println(x) // 輸出 11

    // 無法這樣使用:
    // x = x++ // 錯誤:不允許將 ++ 作為表達式
    }

    📝在這個範例中,我們可以看到 x++ 被當作語句來使用,而不能用在其他表達式中,這樣可以避免複雜的錯誤。

  • 限制指標運算
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package main

    import "fmt"

    func main() {
    var x int = 10
    var ptr *int = &x

    // 無法這樣做:
    // ptr++ // 錯誤:不允許對指標進行運算

    fmt.Println(*ptr) // 輸出 10
    }

    📝這段程式碼展示了 Go 中的指標運算是被限制的,ptr++ 會造成錯誤,這樣可以避免可能導致的指標錯誤。

  • 內建切片(Slice)和字典(Map)
    • 切片範例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      package main

      import "fmt"

      func main() {
      // 宣告切片並初始化
      numbers := []int{1, 2, 3, 4, 5}

      // 增加元素到切片
      numbers = append(numbers, 6)

      // 輸出切片
      fmt.Println(numbers) // 輸出 [1 2 3 4 5 6]

      // 訪問切片元素
      fmt.Println("第一個元素:", numbers[0]) // 輸出 1
      fmt.Println("最後一個元素:", numbers[len(numbers)-1]) // 輸出 6
      }

      📝這段程式展示了如何輕鬆地創建、操作切片(numbers),並使用 append() 函式增加元素。切片讓我們在處理動態數據時,避免了傳統陣列的大小限制。

    • 字典範例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      package main

      import "fmt"

      func main() {
      // 宣告字典
      person := map[string]string{
      "name": "John",
      "age": "30",
      }

      // 訪問字典中的元素
      fmt.Println("姓名:", person["name"]) // 輸出 John
      fmt.Println("年齡:", person["age"]) // 輸出 30

      // 增加元素
      person["address"] = "123 Main St"

      // 輸出更新後的字典
      fmt.Println(person) // 輸出 map[address:123 Main St age:30 name:John]
      }

      📝這段程式碼展示了 Go 中如何使用字典(map)。可以輕鬆地創建一個字典,並透過鍵來訪問、修改資料。Go 的字典支持快速查找,使得資料處理更加高效。


🛠️交叉編譯

編譯過程支援跨平台,能在 Windows 上編譯出適用於 Linux 或 macOS 的執行檔,且不需要額外配置工具鏈,極大簡化了部署。

【範例】<點擊>

📝以下是如何將程式碼編譯為不同平台的可執行檔。只需設定環境變數 GOOS 和 GOARCH,即可編譯出適用於其他作業系統或架構的程式。

1
2
3
4
5
# 在 Linux 上編譯 Windows 執行檔
GOOS=windows GOARCH=amd64 go build -o myprogram.exe main.go

# 在 MacOS 上編譯 Linux 執行檔
GOOS=linux GOARCH=amd64 go build -o myprogram main.go
  • GOOS:作業系統,常見選項包括:
    • windows:Windows
    • darwin:MacOS
    • linux:Linux
    • freebsd:FreeBSD
    • android:Android
    • ios:iOS
  • GOARCH:架構,常見選項包括:
    • amd64:64位元架構
    • 386:32位元架構
    • arm:ARM架構
    • arm64:ARM 64位元架構

🥂天然並行

使用 go 關鍵字創建 goroutine,無需手動管理執行緒,並透過 channel 實現高效的 goroutine 之間的通訊,避免了共享記憶體和鎖的問題。

【範例】<點擊>
  • 使用 goroutines 和 channels 實現簡單的並行工作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package main

    import "fmt"

    func main() {
    ch := make(chan string)

    // 啟動兩個 goroutine,並通過 channel 傳遞數據
    go func() {
    ch <- "Hello from goroutine 1"
    }()
    go func() {
    ch <- "Hello from goroutine 2"
    }()

    // 接收兩個 goroutine 的輸出
    fmt.Println(<-ch)
    fmt.Println(<-ch)
    }
  • 輸出
    1
    2
    Hello from goroutine 2
    Hello from goroutine 1

    📝由於 Go 的 goroutines 是並行執行的,兩個 fmt.Println 的順序可能會有不同,但最終會顯示來自兩個 goroutine 的輸出。


🚮垃圾回收

自動垃圾回收系統,減少了開發者的記憶體管理負擔。它專為並發環境設計,能在不影響效能的情況下高效回收記憶體。


🔗靜態連結

靜態編譯特性使得它非常適合部署到不同的環境中。編譯後的可執行檔包含了所有的依賴,包括標準庫和第三方庫,這使得部署非常簡單。不需要在目標機器上安裝其他庫或運行環境,只需將編譯好的二進位文件傳送到目標系統即可。

【範例】<點擊>
1
go build -a -ldflags '-extldflags "-static"' -o myapp main.go

🧬高效記憶體管理

記憶體管理高效,特別是在高並發場景下。使用 tcmalloc 記憶體分配器,並儘可能將變數分配到堆疊上,減少垃圾回收壓力,提升效能。

【範例】<點擊>
  • 使用記憶體池進行記憶體管理
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    package main

    import (
    "fmt"
    "sync"
    )

    func main() {
    var pool = sync.Pool{
    New: func() interface{} {
    return "New String Object"
    },
    }

    // 從池中獲取對象
    obj := pool.Get().(string)
    fmt.Println("取得的對象:", obj)

    // 使用完後將對象放回池中
    pool.Put("Reused String Object")
    }

    📝在這段程式碼中,我們使用 sync.Pool 管理記憶體池,以提高記憶體使用效率並減少記憶體分配的開銷。


🖥️標準庫與工具鏈

提供了一個非常完整且高效的標準庫,涵蓋了日常開發中的各種需求,從網路程式設計、文件操作,到並行程式、測試框架等都有良好的支援。

除了標準庫,還提供了一個強大的工具鏈,像是自動格式化工具 gofmt、內建的測試框架、性能分析工具 pprof 等,這些工具能幫助開發者在開發過程中保持程式碼一致性、提高程式碼質量,並對程式進行性能調優。

【範例】<點擊>
  • 建立簡單的 Web 伺服器
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    package main

    import (
    "fmt"
    "net/http"
    )

    func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hello, Web Server!")
    }

    func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
    }

    📝這段程式碼使用了 net/http 庫建立了一個簡單的 Web 伺服器,並在 http://localhost:8080 提供了一個歡迎訊息。


👌結語

Go 語言在設計上成功地結合了簡潔性與高效能,從語法的簡單易懂,到天然的並行支持,再到強大的標準庫與工具鏈,無論是大規模系統開發還是高效的並發處理,Go 都能輕鬆應對。透過 Go,開發者可以在享受高效性能的同時,也能提高開發效率,減少複雜度,這使得 Go 成為現代軟體開發的重要選擇之一。

最後建議回顧一下Go | 菜鳥教學目錄,了解其章節目錄。


註:以上參考了
Go
維基百科 - Go
Golang中文学习文档