发布于 2026-01-06 0 阅读
0

国际化 (i18n) 和本地化 (l10n) 分步指南

国际化 (i18n) 和本地化 (l10n) 分步指南

图像

阅读原文

Go 是一种静态编译语言,近年来因其简洁、高效且非常适合开发云应用而广受欢迎。它拥有一个功能强大但文档不足的子包级基础库,该库处理了许多与国际化 (i18n) 和本地化 (l10n) 相关的问题,例如字符编码、文本转换和特定语言环境的文本处理。让我们来看看如何掌握这个库,并使我们的 Go 应用程序能够感知语言环境。

我们提到的这个软件包golang.org/x/text,如果使用得当,几乎可以涵盖应用程序全球化的所有方面。它提供了一系列抽象层,使处理可翻译消息、格式设置、复数规则、Unicode 等更加便捷。

本文将分为两部分。第一部分概述该golang.org/x/text软件包及其在格式化和本地化方面提供的实用工具。Go 语言擅长构建基于微服务的架构,因此在第二部分中,为了延续这一传统,我们将创建一个本地化服务器微服务,以帮助我们全面了解 Go 语言中的 i18n 和 l10n 支持。

在本教程中,我将使用最新的Go v1.10,本教程的代码托管在Github上。

我们出发吧。

套餐概述

Go 程序中的大多数消息都会经过 `fmt` fmt  或某个模板包。`fmt`由多层子包
组成  golang.org/x/text ,提供了大量实用工具和函数,可以使用类似 `fmt` 的 API 来格式化本地化字符串。让我们看看如何在实践中使用它。

消息和目录

消息  是指要传达给用户的某种内容。每条消息都由一个键标识 可以有多种形式。您可以像这样创建一个消息打印机:

p := message.NewPrinter(language.BritishEnglish)
 
p.Printf("There are %v flowers in our garden.", 1500)
Enter fullscreen mode Exit fullscreen mode

调用 NewPrinter 函数时,需要提供语言标签。语言标签用于指定语言。创建标签的方法有很多种,例如:

  • 使用预定义标签。例如: 

language.Greek, language.BrazilianPortuguese
Enter fullscreen mode Exit fullscreen mode

所有预定义标签的列表都列在这里

  • 从字符串值读取。例如: 

language.Make("el"), language.Parse("en-UK")
Enter fullscreen mode Exit fullscreen mode
  • 通过组合标签、基本元素、脚本、区域、变体、[]变体、扩展、[]扩展或错误等类型的部分。例如:
ja, _ := language.ParseBase("ja")
jp, _ := language.ParseRegion("JP")
jpLngTag, _ := language.Compose(ja, jp)
fmt.Println(jpLngTag) // prints ja-JP
Enter fullscreen mode Exit fullscreen mode

如果指定了无效的语言标签,则会得到Und标签的实例,表示未定义的标签。

fmt.Println(language.Compose(language.ParseRegion("AL"))) // prints Und-AL
Enter fullscreen mode Exit fullscreen mode

如果您想了解更多关于语言 API 的信息,请参阅此处的文档

回到我们的消息处理,我们可以指定一台使用不同语言的新打印机,并打印格式化后的字符串。库会自动处理所有本地化的格式变体:

package main
 
import (
 "golang.org/x/text/message"
 "golang.org/x/text/language"
)
 
func main()  {
 p := message.NewPrinter(language.BritishEnglish)
 p.Printf("There are %v flowers in our garden.\n", 1500)
 
 p = message.NewPrinter(language.Greek)
 p.Printf("There are %v flowers in our garden.", 1500)
}
Enter fullscreen mode Exit fullscreen mode

运行此程序后,您将得到:

$ go run main.go
There are 1,500 flowers in our garden.
There are 1.500 flowers in our garden.
Enter fullscreen mode Exit fullscreen mode

现在,为了打印翻译后的消息,我们需要将它们添加到消息目录中,以便 打印机 能够找到具有正确语言标签的消息。

目录 定义了已翻译格式字符串的集合。可以将其视为一组针对特定语言的字典 每个字典都包含一组键对应的翻译。要使用目录,我们需要向其中填充翻译。

实际上,译文将从译员提供的数据源自动导入。我们来看看如何手动操作:

package main
 
import (
 "golang.org/x/text/message"
 "golang.org/x/text/language"
 "fmt"
)
 
func init()  {
 message.SetString(language.Greek, "%s went to %s.",  "%s πήγε στήν %s.")
 message.SetString(language.AmericanEnglish, "%s went to %s.",  "%s is in %s.")
 message.SetString(language.Greek, "%s has been stolen.",  "%s κλάπηκε.")
 message.SetString(language.AmericanEnglish, "%s has been stolen.",  "%s has been stolen.")
        message.SetString(language.Greek, "How are you?", "Πώς είστε?.")
}
 
func main()  {
 p := message.NewPrinter(language.Greek)
 p.Printf("%s went to %s.", "Ο Πέτρος", "Αγγλία")
 fmt.Println()
 p.Printf("%s has been stolen.", "Η πέτρα")
 fmt.Println()
 
 p = message.NewPrinter(language.AmericanEnglish)
 p.Printf("%s went to %s.", "Peter", "England")
 fmt.Println()
 p.Printf("%s has been stolen.", "The Gem")
}
Enter fullscreen mode Exit fullscreen mode

运行此程序后,您将得到以下输出:

$ go run main.go
Ο Πέτρος πήγε στήν Αγγλία.
Η πέτρα κλάπηκε.
Peter is in England.
The Gem has been stolen.%
Enter fullscreen mode Exit fullscreen mode

注意:使用此 SetString  方法时指定的键区分大小写和行,这意味着如果您尝试使用 PrintLn  或添加行尾字符, \n 则该方法将不起作用:

p := message.NewPrinter(language.Greek)
 
p.Printf("%s went to %s.\n", "Ο Πέτρος", "Αγγλία") // will print Ο Πέτρος went to Αγγλία.
p.Println("How are you?") // will print How are you?
Enter fullscreen mode Exit fullscreen mode

通常情况下,您无需创建目录,而是由库自动处理。您也可以选择使用 catalog.Builder 函数以编程方式创建目录。

处理复数形式

如果您需要根据复数形式添加多个字符串翻译,则需要在翻译目录中添加特殊调用来配置这些翻译。子包  公开了一个名为SelectFgolang.org/x/text/feature/plural  的函数  ,用于定义文本中的多个语言复数形式。

下面我列举一些该函数的典型用法:

func init() {
        message.Set(language.Greek, "You have %d. problem",
 plural.Selectf(1, "%d",
 "=1", "Έχεις ένα πρόβλημα",
 "=2", "Έχεις %[1]d πρόβληματα",
 "other", "Έχεις πολλά πρόβληματα",
 ))
        message.Set(language.Greek, "You have %d days remaining",
 plural.Selectf(1, "%d",
 "one", "Έχεις μία μέρα ελεύθερη",
 "other", "Έχεις %[1]d μέρες ελεύθερες",
 ))
 
}
 
func main()  {
 p := message.NewPrinter(language.Greek)
 p.Printf("You have %d. problem", 1)
 fmt.Println()
 p.Printf("You have %d. problem", 2)
 fmt.Println()
 p.Printf("You have %d. problem", 5)
 fmt.Println()
 p.Printf("You have %d days remaining", 1)
 fmt.Println()
 p.Printf("You have %d days remaining", 10)
 fmt.Println()
}
Enter fullscreen mode Exit fullscreen mode

运行此程序后,您将得到以下输出:

$ go run main.go
Έχεις ένα πρόβλημα
Έχεις 2 πρόβληματα
Έχεις πολλά πρόβληματα
Έχεις μία μέρα ελεύθερη
Έχεις 10 μέρες ελεύθερες
Enter fullscreen mode Exit fullscreen mode

该函数提供的情况可以支持多种变体,例如  ,,,,,  zero 并且   还   可以   匹配诸如    或之类 的比较onetwofewmany>x<x

消息中的字符串插值

在其他一些需要处理消息其他可能变体的情况下,您可以分配占位符变量来处理某些特定的语言特征。例如,在前面的示例中,我们使用的复数形式可以写成:

func init() {
        message.Set(language.Greek, "You are %d minute(s) late.",
 catalog.Var("minutes", plural.Selectf(1, "%d", "one", "λεπτό", "other", "λεπτά")),
 catalog.String("Αργήσατε %[1]d ${minutes}."))
 
}
 
func main()  {
 p := message.NewPrinter(language.Greek)
 p.Printf("You are %d minute(s) late.", 1) // prints Αργήσατε 1 λεπτό
 fmt.Println()
 p.Printf("You are %d minute(s) late.", 10)// prints Αργήσατε 10 λεπτά
 fmt.Println()
}

Enter fullscreen mode Exit fullscreen mode

该  catalog.Var 函数会给第一个字符串参数分配一个特殊标签,  minutes 以便根据 %d 参数的值将其替换为更相关的翻译。

货币格式设置

该软件包   golang.org/x/text/currency 处理货币格式化规则。
对于货币,有一些实用的函数可以打印特定于语言环境的金额字符串。例如,以下是一些格式化方法:

package main
 
import (
 "golang.org/x/text/message"
 "golang.org/x/text/language"
 "fmt"
 "golang.org/x/text/currency"
)
 
 
func main()  {
        p := message.NewPrinter(language.English)
        p.Printf("%d", currency.Symbol(currency.USD.Amount(0.1)))
 fmt.Println()
 p.Printf("%d", currency.NarrowSymbol(currency.JPY.Amount(1.6)))
 fmt.Println()
 p.Printf("%d", currency.ISO.Kind(currency.Cash)(currency.EUR.Amount(12.255)))
 fmt.Println()
Enter fullscreen mode Exit fullscreen mode

结果将是:

$ go run main.go  
US$ 0.10
¥ 2
EUR 12.26
Enter fullscreen mode Exit fullscreen mode

加载中……

使用翻译时,通常需要先加载翻译文件,以便应用程序可以使用它们。您可以将这些文件视为静态资源。您可以通过以下几种方式将这些文件与应用程序一起部署:

手动设置翻译字符串

组织翻译的最简单方法是将它们分配到应用程序二进制文件中。您需要手动创建一个条目数组,该数组将在初始化时用于将消息加载到默认目录中。然后,在您的应用程序中,您只需使用 NewPrinter 相应的函数切换语言环境即可。

以下是一个通过在初始化时加载翻译的示例应用程序:

package main
 
import (
 "golang.org/x/text/language"
 "golang.org/x/text/feature/plural"
 "golang.org/x/text/message"
 "golang.org/x/text/message/catalog"
)
 
type entry struct {
 tag, key string
 msg      interface{}
}
 
var entries = [...]entry{
 {"en", "Hello World", "Hello World"},
 {"el", "Hello World", "Για Σου Κόσμε"},
 {"en", "%d task(s) remaining!", plural.Selectf(1, "%d",
 "=1", "One task remaining!",
 "=2", "Two tasks remaining!",
 "other", "[1]d tasks remaining!",
 )},
 {"el", "%d task(s) remaining!", plural.Selectf(1, "%d",
 "=1", "Μία εργασία έμεινε!",
 "=2", "Μια-δυο εργασίες έμειναν!",
 "other", "[1]d εργασίες έμειναν!",
 )},
}

func init()  {
 for _, e := range entries {
     tag := language.MustParse(e.tag)
     switch msg := e.msg.(type) {
     case string:
         message.SetString(tag, e.key, msg)
     case catalog.Message:
         message.Set(tag, e.key, msg)
     case []catalog.Message:
         message.Set(tag, e.key, msg...)
     }
 }
}
 
func main()  {
 p := message.NewPrinter(language.Greek)
 
 p.Printf("Hello World")
 p.Println()
 p.Printf("%d task(s) remaining!", 2)
 p.Println()

 p = message.NewPrinter(language.English)
 p.Printf("Hello World")
 p.Println()
 p.Printf("%d task(s) remaining!", 2)
 
}
Enter fullscreen mode Exit fullscreen mode

运行此程序后,它将输出:

$ go run examples/static/main.go         
Για Σου Κόσμε
Μια-δυο εργασίες έμειναν!
Hello World
Two tasks remaining!%
Enter fullscreen mode Exit fullscreen mode

实际上,虽然这种方法实现起来很简单,但可扩展性不足。它只适用于翻译数量较少的小型应用程序。您需要手动设置翻译字符串,而且很难实现自动化。因此,建议您使用自动加载消息的方式,我将在下文中详细解释具体操作方法。

自动加载消息

传统上,大多数本地化框架都将数据分组存储在按语言动态加载的文件中。您可以将这些文件分发给翻译人员,并在他们完成翻译后将其合并到您的应用程序中。

为了帮助完成这个过程,作者们提供了一个名为“ gotext 用于管理 Go 源代码中的文本”的辅助 CLI 工具。

首先,请确保您使用的是最新版本:

$ go get -u golang.org/x/text/cmd/gotext
Enter fullscreen mode Exit fullscreen mode

运行此工具只会显示可用选项, help  开关不会显示任何其他信息:

$ gotext                        
gotext is a tool for managing text in Go source code.
 
Usage:
 
        gotext command [arguments]
 
The commands are:
 
        update      merge translations and generate catalog
        extract     extracts strings to be translated from code
        rewrite     rewrites fmt functions to use a message Printer
        generate    generates code to insert translated messages

Enter fullscreen mode Exit fullscreen mode

在本教程中,我们将使用 更新 标志,该标志执行多步骤过程,将翻译键提取到文件中,并更新代码以方便地将它们加载到目录中。

创建一个文件 main.go ,添加一些 PrintF  调用,并确保包含命令的注释 go:generate  。

$ touch main.go
Enter fullscreen mode Exit fullscreen mode
  • 文件:main.go
package main
 
//go:generate gotext -srclang=en update -out=catalog/catalog.go -lang=en,el
 
import (
 "golang.org/x/text/language"
 "golang.org/x/text/message"
)
 
func main() {
 p := message.NewPrinter(language.Greek)
 p.Printf("Hello world!")
 p.Println()
 
 p.Printf("Hello", "world!")
 p.Println()
 
 person := "Alex"
 place := "Utah"
 
 p.Printf("Hello ", person, " in ", place, "!")
 p.Println()
 
 // Greet everyone.
 p.Printf("Hello world!")
 p.Println()
 
 city := "Munich"
 p.Printf("Hello %s!", city)
 p.Println()
 
 // Person visiting a place.
 p.Printf("%s is visiting %s!",
 person,
 place)
 p.Println()
 
 // Double arguments.
 miles := 1.2345
 p.Printf("%.2[1]f miles traveled (%[1]f)", miles)
}

Enter fullscreen mode Exit fullscreen mode

运行以下命令:

$ mkdir catalog
$ go generate
Enter fullscreen mode Exit fullscreen mode

然后修改导入语句,使其包含 catalog.go 文件:

*文件:main.go

package main
 
//go:generate gotext -srclang=en update -out=catalog/catalog.go -lang=en,el
 
import (
 "golang.org/x/text/language"
 "golang.org/x/text/message"
      _ "golang.org/x/text/message/catalog"
)
 
...
Enter fullscreen mode Exit fullscreen mode

现在查看项目结构,可以看到已经创建了一些文件:

$ tree .
.
├── catalog
│   └── catalog.go
├── locales
│   ├── el
│   │   └── out.gotext.json
│   └── en
│       └── out.gotext.json
├── main.go
Enter fullscreen mode Exit fullscreen mode

locales 文件夹包含库支持的格式的翻译消息。通常情况下,您需要为此提供翻译。创建一个名为 `locales` 的新文件 messages.gotext.json ,并提供希腊语的翻译。

$ touch locales/el/messages.gotext.json
Enter fullscreen mode Exit fullscreen mode

文件:locales/el/messages.gotext.json

{
  "language": "el",
  "messages": [
    {
      "id": "Hello world!",
      "message": "Hello world!",
      "translation": "Γιά σου Κόσμε!"
    },
    {
      "id": "Hello",
      "message": "Hello",
      "translation": "Γιά σας %[1]v",
      "placeholders": [
        {
          "id": "World",
          "string": "%[1]v",
          "type": "string",
          "underlyingType": "string",
          "argNum": 1,
          "expr": "\"world!\""
        }
      ]
    },
    {
      "id": "Hello {City}!",
      "message": "Hello {City}!",
      "translation": "Γιά σου %[1]s",
      "placeholders": [
        {
          "id": "City",
          "string": "%[1]s",
          "type": "string",
          "underlyingType": "string",
          "argNum": 1,
          "expr": "city"
        }
      ]
    },
    {
      "id": "{Person} is visiting {Place}!",
      "message": "{Person} is visiting {Place}!",
      "translation": "Ο %[1]s επισκέπτεται την %[2]s",
      "placeholders": [
        {
          "id": "Person",
          "string": "%[1]s",
          "type": "string",
          "underlyingType": "string",
          "argNum": 1,
          "expr": "person"
        },
        {
          "id": "Place",
          "string": "%[2]s",
          "type": "string",
          "underlyingType": "string",
          "argNum": 2,
          "expr": "place"
        }
      ]
    },
    {
      "id": "{Miles} miles traveled ({Miles_1})",
      "message": "{Miles} miles traveled ({Miles_1})",
      "translation": "%.2[1]f μίλια ταξίδεψε %[1]f",
      "placeholders": [
        {
          "id": "Miles",
          "string": "%.2[1]f",
          "type": "float64",
          "underlyingType": "float64",
          "argNum": 1,
          "expr": "miles"
        },
        {
          "id": "Miles_1",
          "string": "%[1]f",
          "type": "float64",
          "underlyingType": "float64",
          "argNum": 1,
          "expr": "miles"
        }
      ]
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

现在运行该 go generate  命令和程序,看看翻译是否正在进行:

$ go generate
$ go run main.go
Γιά σου Κόσμε!
Γιά σας world!
 
Γιά σου Κόσμε!
Γιά σου Munich
Ο Alex επισκέπτεται την Utah
1,23 μίλια ταξίδεψε 1,234500%
Enter fullscreen mode Exit fullscreen mode

如果您感兴趣,该 标志会 在源代码中 rewrite 查找对 `functions` 的引用 ,并将其替换为  相应的函数。例如,假设我们有以下程序:fmtp.Print

文件:main.go

func main() {
   p := message.NewPrinter(language.German)
   fmt.Println("Hello world")
   fmt.Printf("Hello world!")
   p.Printf("Hello world!\n")
}

Enter fullscreen mode Exit fullscreen mode

如果您运行以下命令:

$ gotext rewrite -out main.go
Enter fullscreen mode Exit fullscreen mode

然后 main.go 文件将变为:

func main() {
   p := message.NewPrinter(language.German)
   p.Printf("Hello world\n")
   p.Printf("Hello world!")
   p.Printf("Hello world!\n")
}
Enter fullscreen mode Exit fullscreen mode

示例微服务

这是本文的第二部分,我们将在这里运用之前学到的  golang/x/text 软件包知识。我们将构建一个简单的 HTTP 服务器,该服务器提供一个接受用户语言参数的端点。然后,它会尝试将此参数与支持的语言列表进行匹配,并根据最合适的语言环境提供翻译后的响应。

首先,请确保所有依赖项都已安装。

首先创建应用程序框架:

$ go get -u github.com/golang/dep/cmd/dep
$ dep init
$ touch main.go
Enter fullscreen mode Exit fullscreen mode

文件:main.go

package main
 
import (
 "html"
 "log"
 "net/http"
        "fmt"
 "flag"
 "time"
)
 
const (
 httpPort  = "8090"
)
 
func PrintMessage(w http.ResponseWriter, r *http.Request) {
 fmt.Fprintf(w, "Hello, %s", html.EscapeString(r.Host))
}
 
func main() {
 var port string
 flag.StringVar(&port, "port", httpPort, "http port")
 flag.Parse()
 
 server := &http.Server{
 Addr:           ":" + port,
 ReadTimeout:    10 * time.Second,
 WriteTimeout:   10 * time.Second,
 MaxHeaderBytes: 1 << 16,
 Handler:        http.HandlerFunc(PrintMessage)}
 
 log.Fatal(server.ListenAndServe())
}

Enter fullscreen mode Exit fullscreen mode

这个示例 HTTP 服务器目前还不支持翻译。我们可以通过将对 `to` 的调用替换 fmt.FprintF  为对 `to` 的调用 来实现这一点。p.FprintF

func PrintMessage(w http.ResponseWriter, r *http.Request) {
   p := message.NewPrinter(language.English)
   p.Fprintf(w,"Hello, %v", html.EscapeString(r.Host))
Enter fullscreen mode Exit fullscreen mode

将以下代码行添加到源代码中,然后运行 ​​go generate 命令:

//go:generate gotext -srclang=en update -out=catalog/catalog.go -lang=en,el
Enter fullscreen mode Exit fullscreen mode
$ dep ensure -update
$ go generate        
el: Missing entry for "Hello, {Host}".
Enter fullscreen mode Exit fullscreen mode

请提供缺失条目的翻译:

$ cp locales/el/out.gotext.json locales/el/messages.gotext.json
Enter fullscreen mode Exit fullscreen mode

文件:locales/el/messages.gotext.json

{
    "language": "el",
    "messages": [
        {
            "id": "Hello, {Host}",
            "message": "Hello, {Host}",
            "translation": "Γιά σου %[1]v",
            "placeholders": [
                {
                    "id": "Host",
                    "string": "%[1]v",
                    "type": "string",
                    "underlyingType": "string",
                    "argNum": 1,
                    "expr": "html.EscapeString(r.Host)"
                }
            ]
        }
    ]
}

Enter fullscreen mode Exit fullscreen mode

再次运行命令 go generate,并添加对 catalog 包的引用 main.go :

$ go generate

Enter fullscreen mode Exit fullscreen mode

文件:main.go

package main
 
import (
 "html"
 "log"
 "net/http"
 "flag"
 "time"
 "golang.org/x/text/message"
 "golang.org/x/text/language"
 
 _ "go-internationalization/catalog"
)
...

Enter fullscreen mode Exit fullscreen mode

为了确定用户通过 API 请求资源时需要切换哪种语言,我们需要添加一个 Matcher 对象,该对象将根据提供的语言标签列表,从我们支持的语言环境中确定最佳匹配项。
创建一个新的 Matchermessage.DefaultCatalog ,并提供  从工具中获取的  受支持语言环境列表 gotext  :

文件:main.go

var matcher = language.NewMatcher(message.DefaultCatalog.Languages())
Enter fullscreen mode Exit fullscreen mode

添加函数,根据请求参数匹配正确的语言:

文件:main.go

package main
 
import (
 "html"
 "log"
 "net/http"
 "flag"
 "time"
        "context"
 "golang.org/x/text/message"
 "golang.org/x/text/language"
 
 _ "go-internationalization/catalog"

)
 
//go:generate gotext -srclang=en update -out=catalog/catalog.go -lang=en,el
 
var matcher = language.NewMatcher(message.DefaultCatalog.Languages())
 
type contextKey int
 
const (
 httpPort  = "8090"
 messagePrinterKey contextKey = 1
)
 
func withMessagePrinter(next http.HandlerFunc) http.HandlerFunc {
 return func(w http.ResponseWriter, r *http.Request) {
     lang, ok := r.URL.Query()["lang"]
 
     if !ok || len(lang) < 1 {
         lang = append(lang, language.English.String())
     }
     tag,_, _ := matcher.Match(language.MustParse(lang[0]))
     p := message.NewPrinter(tag)
     ctx := context.WithValue(context.Background(), messagePrinterKey, p)
 
     next.ServeHTTP(w, r.WithContext(ctx))
 }
}
...

Enter fullscreen mode Exit fullscreen mode

我只提供了一个从查询字符串中解析出来的参数。你还可以混合使用从 cookie 或 Accept-Language 标头中解析出来的其他标签。

现在你只需要用 PrintMessage  `<script>` 标签 包裹你的处理函数withMessagePrinter ,并从上下文中获取打印机即可:

文件:main.go

...
func PrintMessage(w http.ResponseWriter, r *http.Request) {
 p := r.Context().Value(messagePrinterKey).(*message.Printer)
 p.Fprintf(w,"Hello, %v", html.EscapeString(r.Host))
}
 
func main() {
 var port string
 flag.StringVar(&port, "port", httpPort, "http port")
 flag.Parse()
 
 server := &http.Server{
 Addr:           ":" + port,
 ReadTimeout:    10 * time.Second,
 WriteTimeout:   10 * time.Second,
 MaxHeaderBytes: 1 << 16,
 Handler:        http.HandlerFunc(withMessagePrinter(PrintMessage))}
 
 log.Fatal(server.ListenAndServe())
}

Enter fullscreen mode Exit fullscreen mode

启动服务器并发出一些请求以查看翻译情况:

$ go run main.go
Enter fullscreen mode Exit fullscreen mode

图像
图像

从今往后,世界任你驰骋……

使用短语

Phrase 支持多种语言和框架,包括 Go。它可以轻松导入和导出翻译数据,并查找缺失的翻译,非常方便。此外,您还可以与译员协作,因为拥有 专业的网站本地化服务 对您的网站来说至关重要。如果您想了解更多关于 Phrase 的信息,请参阅 入门指南。您还可以获得 14 天的免费试用。还在等什么呢?

结论

本文探讨了 Go 如何使用 i18n 管理本地化,golang/x/text package并实现了一个提供翻译服务的示例 Web 服务器,解释了各个组件如何协同工作。由于官方文档缺乏实际示例,我希望本文能够以简明易懂的方式阐述在 Go 应用程序中添加 i18n 的基本原理,并能作为日后的参考资料。

这绝非一份详尽的指南,因为每个应用程序的需求和范围要求各不相同。敬请期待更多关于此主题的详细文章。

文章来源:https://dev.to/theodesp/a-step-by-step-guide-to-go-internationalization-i18n--localization-l10n-4ig2