当一个源字符串不足以覆盖所有情况时,就需要用到复数和 select——翻译结果会随数字或类别而变化。@lingo.dev/react 提供了两个顺手的辅助方法(l.plural 和 l.select),底层会编译成 ICU MessageFormat,因此译者面对的是标准语法,运行时也无需改变。
复数#
l.plural(count, forms, { context }) 会根据 count 和当前语言环境的 CLDR 复数规则,选出正确的形式。
const l = useLingo();
l.plural(items.length, {
one: "1 item",
other: "{count} items",
}, { context: "Cart summary" });
// → "1 item" (en, count=1) / "5 items" (en, count=5)
// → "1 Eintrag" / "5 Einträge" (de, after translation)不同语言环境的形式#
形式映射支持全部 CLDR 复数类别——zero、one、two、few、many、other。不同语言环境按需选用:
- 英语使用
one+other(1 和其余所有情况) - 俄语使用
one+few+many+other(1;2–4;5–20;21、31……) - 阿拉伯语会用到全部六种
- 日语只使用
other(没有复数区分)
你只需要提供源语言环境所用的形式——其余部分由译者按目标语言环境补齐。
{count} 会自动插入到任意复数形式中。你不需要通过 values 显式传入——它来自第一个参数。
与其他占位符一起使用#
如果一句话里既有数量又有其他变量,直接把这些变量写进形式字符串中;它们会原样传递给 ICU。
l.plural(notifications.length, {
one: "1 message from {sender}",
other: "{count} messages from {sender}",
}, { context: "Inbox header" });然后在调用时传入对应的值——不过要注意,l.plural 的签名里只有 { context }。遇到这种混合场景,请直接使用 l.text,并写成 ICU 复数语法:
l.text(`{count, plural, one {1 message from {sender}} other {# messages from {sender}}}`, {
values: { count: notifications.length, sender: user.name },
context: "Inbox header",
});# 这个标记会被原样替换为计数值——如果你想直接输出数字,而不使用花括号插值形式,这会很方便。
Select#
l.select(value, forms, { context }) 会根据字符串键选择对应的形式(性别、角色、内容类型——任何分类值都适用)。
l.select(user.gender, {
male: "He uploaded a photo",
female: "She uploaded a photo",
other: "They uploaded a photo",
}, { context: "Activity feed" });other 是必填的兜底项。匹配是精确的——不支持模糊匹配,也不会忽略大小写。
Selectordinal#
处理序数(1st、2nd、3rd)时,请通过 l.text 直接使用 ICU 的 selectordinal:
l.text(`You finished in {place, selectordinal, one {#st} two {#nd} few {#rd} other {#th}} place`, {
values: { place: rank },
context: "Leaderboard",
});
// → "You finished in 1st place" / "2nd" / "3rd" / "4th, 5th, ..."会编译成什么#
l.plural 和 l.select 都会生成一个 ICU MessageFormat 字符串,并将它传给 l.text。编译后的形式会被 lingo extract 提取并存入你的语言环境文件中——译者编辑的是 ICU 语法本身,而不是 JS 对象字面量。
例如:l.plural(n, { one: "1 item", other: "{count} items" }, { context: "Cart" }) 会被提取为:
{count, plural, one {1 item} other {{count} items}}这意味着译者可以按不同语言环境调整类别,包括源语言里没有的那些。比如俄语可以变成 {count, plural, one {...} few {...} many {...} other {...}},而完全不需要改动代码。
何时不该使用这些#
- 简单的“1 或多个”布尔判断。 在
if里写两个l.text调用就足够了,而且译者也更容易看明白。 - 不直接面向用户的程序枚举。 复数 / select 用于翻译分类消息,不适合拿来驱动应用逻辑。
下一步看什么#
- useLingo——了解
l.text和l.rich的基础语义。 - Formatting——通过原生 Intl 进行数字、货币、日期和列表格式化。
