公開日:

Go言語のローカライゼーションパッケージ go-l10nを公開

Authors
  • Name

Go言語用のローカライゼーション(自然言語メッセージ翻訳)のためのパッケージをOSSとして公開した。

このローカライゼーションパッケージは、Movable Typeのローカライゼーションにインスパイアされた仕様となっている。


英語文をキーにした文字列マップによるシンプルな辞書

メッセージ翻訳辞書といえば、PO/POT形式やYAMLに記述する方法をよく目にする。また、Go言語でも標準的にgolang.org/x/text/messageが用意されている。

実はそこまで詳しくないので勘違いがあると恐縮だが、これらの方法はメッセージキーを別途用意する。JSONで例えるとこのような感じだ。

yaml
greeting:
  en: Hello, %s
  ja: こんにちは、%sさん

プログラム上ではgreetingを用いて言語に応じたメッセージを参照する。

合理的ではあるのだが、自分には認知的負荷が高かった。例えば%sのようにプレースホルダを持っていても、実際のメッセージを見ないとわからない。

また、メッセージはそのときの判断でわかりやすいものに変更することも多い。するとその場では変更できないので、毎回辞書ファイルから該当箇所を探して修正し…と手間がかかる。

しかしMovable Typeのローカライゼーションは違った。英語のメッセージ自体をキーとし、プログラム上における文字列マップ(連想配列)で 辞書を表現する。

go
jpDictionary := map[string]string{
  "Hello, %s": "こんにちは, %sさん"
}

シンプルすぎて弱点もある。

  • キーが長いので照会が遅い
  • 単数形/複数形など動的なローカライゼーションに対応できない

しかしこの仕組みにより、とりあえず英語メッセージでプログラムの実装を進め、UIのフィーリングを確認できる。

そしてメッセージキーと実メッセージの対応にも記憶領域を奪われることもない。それが心地よかった。

そこでGo言語に向けて自分でも用意したという経緯である。

使い方

以下のようにl10n.Tに英語メッセージをキーとして渡すことで可読性の高いコードを書ける。

翻訳はinitにおいてl10n.Registerを通してマップを渡す。これでグローバルな日本語辞書に翻訳がマージされる。

go
package main

import (
    "fmt"
    "github.com/ideamans/go-l10n"
)

func main() {
    fmt.Println(l10n.T("Hello, World!"))
}

func init() {
    l10n.Register("ja", l10n.LexiconMap{
        "Hello, World!":     "こんにちは、世界!",
    })
}

そのほか、環境変数から言語の自動判別、テスト時は英語に固定する機能、fmt.Formatfmt.Errorのシュガーシンタックスなどがある。

詳しくはREADMEをご覧いただきたい。