本文 AI 產出,尚未審核

Golang 基本語法與資料型態 – 基本資料型別(int、float、bool、string)

簡介

在任何程式語言中,資料型別都是最基礎也是最重要的概念之一。它決定了變數可以儲存什麼樣的值、如何在記憶體中排列,甚至會影響程式的效能與安全性。Go(又稱 Golang)設計了簡潔且安全的型別系統,讓開發者在寫出可讀性高的程式同時,也能避免許多常見的錯誤。

本單元聚焦於四個最常使用的基本型別:

  • int – 整數
  • float – 浮點數(float32float64
  • bool – 布林值
  • string – 字串

掌握這四種型別的特性與使用方式,能讓你在 資料處理、演算法實作、API 開發 等實務情境中快速上手,並寫出正確、易維護的程式碼。


核心概念

1. 整數型別 intint8int16int32int64

型別 位元寬度 取值範圍(正負)
int 平台相關(32 或 64) -2^(n-1) ~ 2^(n-1)-1
int8 8 -128 ~ 127
int16 16 -32768 ~ 32767
int32 32 -2,147,483,648 ~ 2,147,483,647
int64 64 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
  • int 會根據執行平台自動選擇 32 或 64 位元,對大多數應用來說是最便利的選擇。
  • 若需要明確控制範圍(例如與外部二進位協定對接),請使用固定寬度的型別(int8int16…)。

範例 1:基本整數運算與類型轉換

package main

import (
	"fmt"
)

func main() {
	var a int = 42          // 預設 int
	var b int64 = 1_000_000 // 使用 int64,底線可視為千位分隔符

	// 顯式類型轉換:int -> int64
	sum := int64(a) + b
	fmt.Printf("sum = %d (type %T)\n", sum, sum)

	// 整數除法會自動捨去小數部分
	quotient := b / 3
	fmt.Printf("quotient = %d\n", quotient)
}

重點:在 Go 中不同寬度的整數不能直接相加,必須先做顯式的類型轉換(int64(a))。


2. 浮點數型別 float32float64

型別 位元寬度 有效位數(約) 最大/最小值(正)
float32 32 6-7 位數 3.4e38 / 1.4e-45
float64 64 15-16 位數 1.8e308 / 5.0e-324
  • 預設的浮點型別是 float64,提供更高精度且在大多數硬體上效能相近。
  • 若在記憶體或網路傳輸上有嚴格限制,或是需要與 GPU/圖形 API 互動,則可選擇 float32

範例 2:浮點運算與精度比較

package main

import (
	"fmt"
	"math"
)

func main() {
	var f32 float32 = 0.1
	var f64 float64 = 0.1

	// 直接比較會得到 false,因為二進位無法精確表示 0.1
	fmt.Println("f32 == 0.1 ?", f32 == 0.1) // false
	fmt.Println("f64 == 0.1 ?", f64 == 0.1) // false

	// 使用 math.Abs 以及容忍度 (epsilon) 進行近似比較
	const epsilon = 1e-9
	if math.Abs(float64(f64)-0.1) < epsilon {
		fmt.Println("f64 與 0.1 近似相等")
	}
}

技巧:在金融或科學計算中,避免直接比較浮點數,改用容忍度(epsilon)或使用 math/big 套件的高精度類型。


3. 布林值 bool

bool 只有兩個合法值:truefalse。它常用於條件判斷、迴圈控制與邏輯運算。

範例 3:布林運算與條件分支

package main

import "fmt"

func main() {
	isAdult := true
	hasTicket := false

	// && (AND) 與 || (OR) 的短路行為
	if isAdult && hasTicket {
		fmt.Println("可以進入")
	} else if isAdult && !hasTicket {
		fmt.Println("需先購票")
	} else {
		fmt.Println("未滿年齡,無法入場")
	}
}

提醒:Go 的布林運算是短路的,右側表達式只有在需要時才會被求值,這點常用來避免 nil 指標的存取錯誤。


4. 字串 string

字串在 Go 中是 不可變(immutable)的 UTF-8 編碼序列。

  • 直接使用雙引號(")或反引號(`)宣告。
  • 反引號字面值會保留所有換行與空白,常用於多行文字或正則表達式。

範例 4:字串操作與 Unicode 處理

package main

import (
	"fmt"
	"strings"
	"unicode/utf8"
)

func main() {
	// 雙引號字面值
	hello := "Hello, 世界"
	fmt.Println(hello)

	// 取得字元長度(以 rune 為單位)
	fmt.Printf("字元數: %d\n", utf8.RuneCountInString(hello))

	// 字串切割
	parts := strings.Split(hello, ",")
	fmt.Printf("切割結果: %v\n", parts)

	// 反引號多行字串
	raw := `第一行
第二行	含 Tab
第三行`
	fmt.Println("原始多行字串:")
	fmt.Println(raw)
}

要點

  • len(string) 回傳的是 位元組 數,對 Unicode 字元(rune)需使用 utf8.RuneCountInString
  • 字串不可變,若需要頻繁的字串拼接,建議使用 strings.Builderbytes.Buffer

常見陷阱與最佳實踐

陷阱 說明 解決方式
類型不匹配 整數與浮點數、不同寬度的整數直接相加會編譯錯誤。 使用顯式類型轉換,或在設計時統一使用 int / float64
浮點精度問題 0.1、0.2 等十進位小數在二進位中無法精確表示。 使用容忍度比較或 math/big 的高精度類型。
字串切割產生空字串 strings.Split("a,b,", ",") 會在結尾產生空字串。 檢查結果或使用 strings.Split(strings.TrimSuffix(s, ","), ",")
Unicode 計算錯誤 len(str) 計算的是位元組,不是字元。 使用 utf8.RuneCountInString[]rune(str) 轉型。
布林短路誤用 if a && b 中,若 afalseb 不會被評估,可能導致預期外的行為。 確認短路行為是否符合需求,必要時分開寫判斷式。

最佳實踐

  1. 統一使用 intfloat64:除非有特殊需求,選擇平台預設的寬度可減少類型轉換的負擔。
  2. 避免魔法數字:將常用的常數(例如 Pi = 3.1415926)定義為 const,提升可讀性與維護性。
  3. 字串拼接使用 strings.Builder:在大量拼接時,+ 會產生大量暫時物件,影響效能。
  4. 使用 iota 建立枚舉型別:若需要一組相關的整數常數,可利用 iota 產生自動遞增值。
  5. 加上適當的註解:尤其在類型轉換或浮點比較的地方,註明「為什麼這樣做」能防止日後的誤解。

實際應用場景

場景 可能用到的型別 範例說明
Web API 請求/回應 int(ID、狀態碼)、string(JSON key) 從資料庫取得 int ID,轉成 JSON 字串回傳。
金融計算 float64(金額)、bool(是否已付款) 使用 float64 進行利息計算,最後以 bool 標示是否超過信用額度。
資料庫存取 int64(自增主鍵)、string(文字欄位) Go 的 database/sql 會自動映射 BIGINTint64
IoT 感測器資料 float32(溫度、濕度) 受限於記憶體與頻寬,使用 float32 可減少傳輸負荷。
文字處理與日誌 stringbool(是否啟用 debug) strings.Builder 組合大量日誌字串,使用 bool 控制是否寫入檔案。

總結

  • intfloat64boolstring 是 Go 程式設計中最常見的四大基礎型別,熟悉它們的範圍、預設寬度與行為是寫出正確程式的根本。
  • 類型安全 是 Go 的核心精神之一,透過顯式的類型轉換與編譯期檢查,我們能在開發早期就捕捉到潛在的錯誤。
  • 在實務開發中,根據 效能、記憶體、跨平台 的需求選擇合適的寬度(例如 int64 vs intfloat32 vs float64),並遵守 最佳實踐(如使用 strings.Builder、避免直接比較浮點數),能讓程式更具可讀性與可維護性。

掌握了這些基本資料型別後,你就能自信地進入更高階的 Go 主題,如結構體、介面、併發模型(goroutine、channel)等,為日後開發大型系統奠定堅實基礎。祝你在 Golang 的學習旅程中一路順風! 🚀