[golang]Go 官方提供的多語系(i18n)解決方案之一(golang.org/x/text/language)

 golang.org/x/text/language 是 Go 官方提供的多語系(i18n)解決方案之一,主要用於 語言偵測、標記匹配和格式化。但它本身不提供翻譯功能,要搭配 golang.org/x/text/message 來處理翻譯。



安裝

go get golang.org/x/text/language
go get golang.org/x/text/message


1. 使用 message 來處理翻譯

這種方式適用於小型應用程式,直接在程式內定義翻譯字串。

package main
import ( "fmt" "golang.org/x/text/language" "golang.org/x/text/message" ) func main() { // 註冊翻譯內容 message.SetString(language.English, "hello", "Hello, World!") message.SetString(language.Chinese, "hello", "你好,世界!") message.SetString(language.Japanese, "hello", "こんにちは、世界!") // 偵測使用者語言(這裡假設使用中文) userLang := language.Chinese // 建立翻譯器 p := message.NewPrinter(userLang) // 輸出翻譯結果 fmt.Println(p.Sprintf("hello")) // 你好,世界! }

💡 適用場景

  • 小型應用
  • 內建少量翻譯字串
  • 不需要從 JSON/TOML 文件載入翻譯


2. 使用 Matcher 來自動選擇語言

如果你的應用支援多語系,可以讓程式根據 Accept-Language 標頭來選擇最佳匹配語言。

package main
import ( "fmt" "golang.org/x/text/language" ) func main() { // 定義支援的語言 supported := []language.Tag{ language.English, // 英文 language.Chinese, // 中文 language.Japanese, // 日文 } // 使用 Matcher 來選擇最佳語言 matcher := language.NewMatcher(supported) // 模擬不同的使用者語言偏好 userPref, _ := language.MatchStrings(matcher, "zh-TW", "en-US") // 顯示匹配結果 fmt.Println("最佳匹配語言:", userPref) }

輸出:

最佳匹配語言: zh

適用場景

  • 根據 Accept-Language 選擇最佳語言
  • 需要支援多種語言


3. 搭配 Plural 處理複數規則

有時候我們需要根據數量來改變翻譯內容,例如:

  • 1 apple ✅
  • 5 apples ✅

這可以透過 message.Set 和 message.NewPrinter 來實現。

package main
import ( "fmt" "golang.org/x/text/language" "golang.org/x/text/message" ) func main() { // 註冊翻譯 message.Set(language.English, "apple", message.Plural(1, "One apple", "Many apples")) message.Set(language.Chinese, "apple", message.Plural(1, "一顆蘋果", "多顆蘋果")) // 英文輸出 p := message.NewPrinter(language.English) fmt.Println(p.Sprintf("apple", 1)) // One apple fmt.Println(p.Sprintf("apple", 5)) // Many apples // 中文輸出 p = message.NewPrinter(language.Chinese) fmt.Println(p.Sprintf("apple", 1)) // 一顆蘋果 fmt.Println(p.Sprintf("apple", 5)) // 多顆蘋果 }

適用場景

  • 根據數量變化翻譯內容(如 複數規則
  • 需要更細緻的語系支援


4. 搭配 JSON 檔案實現完整翻譯系統

如果要用 JSON 檔案管理翻譯,可以手動載入翻譯內容。

建立 locales.json

{
"en": {
"hello": "Hello, World!",
"greeting": "Hello, {name}!"
},
"zh": {
"hello": "你好,世界!",
"greeting": "你好,{name}!"
}
}

使用 Go 讀取 JSON

package main import (
"encoding/json"
"fmt"
"golang.org/x/text/language"
"io/ioutil"
"os"
) // TranslationMap 用來儲存語系對應的字串
type TranslationMap map[string]map[string]string func main() {
// 讀取翻譯檔案
file, err := os.Open("locales.json")
if err != nil {
panic(err)
}
defer file.Close() byteValue, _ := ioutil.ReadAll(file)
// 解析 JSON
var translations TranslationMap
if err := json.Unmarshal(byteValue, &translations); err != nil {
panic(err)
}
// 設定使用者語系
userLang := "zh"
// 取得翻譯
fmt.Println(getTranslation(translations, userLang, "hello")) // 你好,世界!
fmt.Println(getTranslation(translations, userLang, "greeting", "小明")) // 你好,小明!
} // getTranslation 取得翻譯字串
func getTranslation(t TranslationMap, lang, key string, args ...interface{}) string {
// 確保語言存在
if _, ok := t[lang]; !ok {
lang = "en" // 預設回退語言
}
// 取得字串
text, exists := t[lang][key]
if !exists {
return key // 找不到則回傳 key
}
// 插入參數
return fmt.Sprintf(text, args...)
}

適用場景

  • 需要從 JSON 檔案載入翻譯
  • 適用於 動態翻譯更新
  • 可擴充性高,支援多語系


總結

方案適用場景特色
message.SetString小型應用,內建翻譯簡單易用
language.Matcher多語系切換可根據 Accept-Language 自動選擇
message.Plural複數規則處理適用於多變化詞彙
JSON 翻譯檔案大型應用,動態更新可擴充性高,管理大量翻譯

如果只是處理簡單的翻譯,建議使用 message.SetString

留言

這個網誌中的熱門文章

[Kotlin]如何學習Kotlin

[golang]如何使用 gorm 高效執行批量插入 (可以透過 Create()、CreateInBatches(),或者 原生 SQL 語句 來提升效率)

[Kotlin]Kotlin Multiplatform (KMP) 如何安裝使用和部署