Panduan Lengkap Pengantarabangsaan Go
Daripada fail mesej hingga resolusi lokal yang selamat untuk goroutine: sediakan i18n dalam aplikasi Go anda dengan go-i18n, kemudian automatikkan terjemahan dengan AI.
Pasang go-i18n
go-i18n ialah pustaka pengantarabangsaan paling popular untuk Go. Pustaka ini menggunakan peraturan bentuk jamak CLDR, templat Go untuk interpolasi pemboleh ubah, serta menyokong fail mesej JSON, TOML, dan YAML. Anda juga memerlukan golang.org/x/text untuk pemadanan tag bahasa.
go get -u github.com/nicksnyder/go-i18n/v2/i18n
go get -u golang.org/x/text/languageCipta Fail Mesej
Cipta satu fail JSON bagi setiap bahasa dalam direktori locales. Setiap mesej mempunyai ID dan satu atau beberapa bentuk jamak. Go-i18n menggunakan sintaks templat Go (kurungan berombak berganda dengan awalan titik) untuk interpolasi pemboleh ubah.
{
"HelloWorld": { "other": "Hello, World!" },
"Greeting": { "other": "Hello, {{.Name}}!" },
"ItemCount": {
"one": "{{.Count}} item",
"other": "{{.Count}} items"
},
"WelcomeBack": {
"other": "Welcome back, {{.Name}}. You have {{.Count}} messages."
}
}Muatkan Bundle
Bundle ialah daftar pusat go-i18n. Cipta satu semasa permulaan, daftarkan format fail anda, dan muatkan semua fail mesej. Bundle selamat untuk goroutine — cipta sekali dan kongsikannya merentas aplikasi anda.
package main
import (
"encoding/json"
"fmt"
"github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
func main() {
// 1. Create a bundle with a default language
bundle := i18n.NewBundle(language.English)
// 2. Register the unmarshal function for your file format
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
// 3. Load message files
bundle.MustLoadMessageFile("locales/en.json")
bundle.MustLoadMessageFile("locales/ja.json")
bundle.MustLoadMessageFile("locales/de.json")
// 4. Create a localizer and localize a message
localizer := i18n.NewLocalizer(bundle, "ja")
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "HelloWorld",
})
fmt.Println(msg) // "こんにちは、世界!"
}Gunakan Localizer
Cipta Localizer bagi setiap permintaan dengan bahasa pilihan pengguna. Localizer memilih mesej daripada Bundle, mengendalikan pemaparan templat dengan enjin text/template Go, dan memilih bentuk jamak yang betul berdasarkan PluralCount.
// Simple message
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "HelloWorld",
})
// Message with template data
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "Greeting",
TemplateData: map[string]interface{}{
"Name": "Alice",
},
})
// "Hello, Alice!" (en) or "こんにちは、Aliceさん!" (ja)
// Plural + template data
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "ItemCount",
PluralCount: 5,
TemplateData: map[string]interface{}{
"Count": 5,
},
})
// "5 items" (en) or "5個のアイテム" (ja)
// Combined: plurals + multiple variables
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "WelcomeBack",
TemplateData: map[string]interface{}{
"Name": "Alice",
"Count": 3,
},
})func handler(w http.ResponseWriter, r *http.Request) {
// Accept-Language: ja,en;q=0.9,de;q=0.8
accept := r.Header.Get("Accept-Language")
// NewLocalizer accepts multiple languages — first match wins
localizer := i18n.NewLocalizer(bundle, accept)
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "HelloWorld",
})
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.Write([]byte(msg))
}Kendalikan Peraturan Bentuk Jamak
go-i18n melaksanakan peraturan bentuk jamak CLDR untuk semua bahasa. Bahasa Inggeris mempunyai 2 bentuk (satu, lain). Bahasa Arab mempunyai 6 (sifar, satu, dua, sedikit, banyak, lain). Bahasa Jepun mempunyai 1 (lain). Tentukan semua bentuk yang diperlukan dalam fail mesej anda — go-i18n memilih bentuk yang betul berdasarkan PluralCount.
// English: 2 forms (one, other)
{
"ItemCount": {
"one": "{{.Count}} item",
"other": "{{.Count}} items"
}
}
// Arabic: 6 forms (zero, one, two, few, many, other)
{
"ItemCount": {
"zero": "لا عناصر",
"one": "عنصر واحد",
"two": "عنصران",
"few": "{{.Count}} عناصر",
"many": "{{.Count}} عنصرًا",
"other": "{{.Count}} عنصر"
}
}
// Japanese: 1 form (other)
{
"ItemCount": {
"other": "{{.Count}}個のアイテム"
}
}// go-i18n selects the correct plural form based on PluralCount
localizer := i18n.NewLocalizer(bundle, "ar")
msg := localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "ItemCount",
PluralCount: 3,
TemplateData: map[string]interface{}{
"Count": 3,
},
})
// Arabic "few" form: "3 عناصر"
msg = localizer.MustLocalize(&i18n.LocalizeConfig{
MessageID: "ItemCount",
PluralCount: 1,
TemplateData: map[string]interface{}{
"Count": 1,
},
})
// Arabic "one" form: "عنصر واحد"Pengesanan Lokal
Dalam aplikasi web, kesan bahasa pilihan pengguna daripada beberapa sumber: parameter pertanyaan, kuki, pengepala Accept-Language, atau segmen laluan URL. Gunakan golang.org/x/text/language.Matcher untuk perundingan bahasa yang mematuhi BCP 47.
// detectLocale resolves the user's preferred language.
// Priority: query param > cookie > Accept-Language header > default
func detectLocale(r *http.Request, matcher language.Matcher) string {
// 1. Explicit query parameter: ?lang=ja
if lang := r.URL.Query().Get("lang"); lang != "" {
tag, _, _ := matcher.Match(language.Make(lang))
return tag.String()
}
// 2. Cookie from previous selection
if cookie, err := r.Cookie("lang"); err == nil {
tag, _, _ := matcher.Match(language.Make(cookie.Value))
return tag.String()
}
// 3. Accept-Language header
accept := r.Header.Get("Accept-Language")
if accept != "" {
tags, _, _ := language.ParseAcceptLanguage(accept)
if len(tags) > 0 {
tag, _, _ := matcher.Match(tags...)
return tag.String()
}
}
return "en" // 4. Default
}
// Usage:
matcher := language.NewMatcher([]language.Tag{
language.English, language.Japanese,
language.German, language.Spanish,
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
locale := detectLocale(r, matcher)
localizer := i18n.NewLocalizer(bundle, locale)
// ... use localizer
})Baiki Sandaran Setiap Kekunci dengan go-locale-chain
go-i18n mempunyai batasan yang diketahui: setelah sesuatu lokal sepadan (mempunyai terjemahan yang dimuatkan), kekunci yang tiada tidak beralih kepada lokal seterusnya dalam rantaian. Pengguna pt-BR dengan fail pt-BR yang baru diterjemahkan sebahagian akan mendapat rentetan kosong dan bukannya bersandar kepada pt-PT atau pt. go-locale-chain membaikinya dengan resolusi sandaran setiap kekunci merentas 75 rantaian lokal terbina dalam.
go get github.com/i18n-agent/go-locale-chainpackage main
import (
"encoding/json"
"fmt"
"github.com/nicksnyder/go-i18n/v2/i18n"
localechain "github.com/i18n-agent/go-locale-chain"
"golang.org/x/text/language"
)
func main() {
// 1. Configure fallback chains (call once at startup)
localechain.Configure()
// 2. Set up go-i18n bundle as usual
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
bundle.MustLoadMessageFile("locales/en.json")
bundle.MustLoadMessageFile("locales/pt.json")
bundle.MustLoadMessageFile("locales/pt-PT.json")
bundle.MustLoadMessageFile("locales/pt-BR.json")
// 3. Resolve with per-key fallback
result, _ := localechain.ResolveWithLoader("pt-BR", func(locale string) (map[string]string, error) {
localizer := i18n.NewLocalizer(bundle, locale)
messages := make(map[string]string)
for _, id := range []string{"hello", "goodbye", "thanks"} {
msg, err := localizer.Localize(&i18n.LocalizeConfig{MessageID: id})
if err == nil {
messages[id] = msg
}
}
return messages, nil
})
fmt.Println(result["hello"]) // "Olá (BR)" — from pt-BR
fmt.Println(result["goodbye"]) // "Adeus (PT)" — fallback to pt-PT
fmt.Println(result["thanks"]) // "Obrigado" — fallback to pt
}// Standalone: zero external dependencies, works with any format
localechain.Configure()
result, _ := localechain.ResolveWithLoader("es-MX", func(locale string) (map[string]string, error) {
data, err := os.ReadFile(fmt.Sprintf("locales/%s.json", locale))
if err != nil {
return nil, err // Locale file doesn't exist — skip
}
var msgs map[string]string
json.Unmarshal(data, &msgs)
return msgs, nil
})
// es-MX -> es-419 -> es: each key resolved from most specific localeAutomatikkan Terjemahan
Selepas persediaan i18n selesai, terjemahkan fail lokal anda menggunakan AI. Jana terjemahan untuk semua bahasa sasaran daripada fail sumber bahasa Inggeris — secara langsung daripada IDE atau dalam saluran CI/CD anda.
# In your IDE, ask your AI assistant:
> Translate locales/en.json to German, Japanese, and Spanish
✓ locales/de.json created (1.2s)
✓ locales/ja.json created (1.5s)
✓ locales/es.json created (1.1s)
# Or use the CLI in CI/CD:
npx i18n-agent translate locales/en.json --lang de,ja,esAutomatikkan Kualiti Terjemahan
Kesilapan Umum
PluralCount dan TemplateData Tidak Sepadan
RegisterUnmarshalFunc Tiada
Sandaran Setiap Kekunci Tidak Berfungsi
Sintaks Templat: {'{.Var}'}, Bukan {'{Var}'}
Struktur Fail yang Disyorkan
my-go-app/
├── locales/
│ ├── en.json # Source language (English)
│ ├── de.json # German translations
│ ├── ja.json # Japanese translations
│ ├── es.json # Spanish translations
│ ├── pt.json # Portuguese (base)
│ ├── pt-PT.json # Portuguese (Portugal)
│ └── pt-BR.json # Portuguese (Brazil)
├── i18n/
│ ├── bundle.go # Bundle initialization
│ ├── detect.go # Locale detection logic
│ └── middleware.go # HTTP middleware for locale
├── main.go
├── go.mod
└── go.sumCuba i18n Agent Sekarang
Lepaskan fail terjemahan anda di sini
JSON, YAML, PO, XML, CSV, Markdown, Properties
atau klik untuk semak imbas
Bahasa sasaran
Sandaran Lokal dengan go-locale-chain
Apabila kekunci terjemahan tiada dalam lokal serantau seperti pt-BR, go-i18n terus beralih kepada bahasa lalai dan bukannya menyemak lokal induk pt terlebih dahulu.
go get github.com/i18n-agent/go-locale-chainimport localechain "github.com/i18n-agent/go-locale-chain"
chain := localechain.New(localechain.Config{
Fallbacks: map[string][]string{
"pt-BR": {"pt", "en"},
"zh-Hant-HK": {"zh-Hant", "zh", "en"},
},
})Lihat Panduan Sandaran Bahasa kami untuk senarai lengkap rangka kerja yang disokong dan 75 rantaian terbina dalam. Learn more →