正在载入

等待时间过长时请刷新页面

编写于

最近更新

语言字段引用

LangText、LangList 和 LangMap 表示语言对象中的稳定字段引用。它们适合交给命令、消息和界面等长期保存文本来源的组件。

普通 String 保存当前值快照;语言字段引用在每次 resolve() 时读取语言服务的当前快照,因此语言重载或切换后仍可使用原引用。

定义引用字段

@LangPack(filePath = "main")
public class MainLanguage {
    public Command command = new Command();

    public static class Command {
        public LangText description = LangText.of("执行命令");
        public LangList tips = LangList.of("默认提示");
        public LangMap buttons = LangMap.of(
                "confirm", "确认",
                "cancel", "取消"
        );
    }
}

LangText.of(...) 等方法声明代码默认值。语言类由 LangService.bind(...) 绑定时,服务按照字段结构确定路径,并把声明对象替换成受管理引用。因此,不应直接构造语言类并把未绑定字段交给其他服务。

MainLanguage lang = lin.linFile().language().bind(MainLanguage.class);

资源目录、字段命名和 locale 选择见语言文件 ⇱。

读取文本

不传 locale 时读取当前全局语言:

String description = lang.command.description.resolve();
List<String> tips = lang.command.tips.resolve();
Map<String, String> buttons = lang.command.buttons.resolve();

也可以显式读取某个 locale:

String description = lang.command.description.resolve("en_GB");

列表和映射结果都是不可修改的快照。需要长期保存时,应保存 LangList 或 LangMap,而不是某次 resolve() 的结果。

不要依赖 toString() 隐式解析文本。需要字符串时显式调用 resolve(),或者把引用交给支持 TextSource 的服务。

集合规则

LangList 表示整个字符串列表,LangMap 表示键和值都是字符串的单层映射。嵌套 Map、嵌套 List 以及 List<LangText>、Map<String, LangText> 不属于集合引用的数据模型。

非空的 LangMap.of(...) 默认值会参与缺失键补齐,适合键集合固定的语言内容。键由用户自由定义时,应使用空默认值:

public LangMap customMessages = LangMap.of();

三种引用都可以放在 @LangPack 语言对象的嵌套对象中,仍由根类上的语言包声明统一管理。

与其他服务配合

命令描述和参数标签可以直接接收 LangText,从而在帮助页面中显示重载后的文本。注册方式见注册命令 ⇱。

LangText 同时实现 TextSource,可以直接交给消息服务。作为消息变量时,LangText 会作为可渲染文本处理,普通 String 则会被安全转义。完整规则见消息服务 ⇱。

配置文件中的 @lang(...) 不是 LangText 字段本身。其语法、字段类型和绑定顺序见配置文件中的语言 ⇱。

生命周期

LangService.reload() 和 lin.settings().apply() 都会更新语言服务的内部快照,不替换已经安装的引用。已有 LangText、LangList 和 LangMap 可以继续使用。

关闭 Facade 后,旧服务及其引用不应继续使用。创建新 Facade 后应重新绑定语言对象。业务代码也不应重新给引用字段赋值;修改翻译应编辑语言文件并执行重载。

讨论

请登录账号