多语言输出
六种盘面语言、哪些字段会被翻译、换盘面语言对结果的影响,以及标识与译名的双向换算。
适合:开发者
支持的盘面语言
「盘面语言」指排盘结果里那些人读的文本用哪种语言写,与你用哪种编程语言调用无关。
| 取值 | 语言 | Rust 枚举 |
|---|---|---|
zh-CN | 简体中文(默认) | Language::ZhCN |
zh-TW | 繁体中文 | Language::ZhTW |
en-US | 英文 | Language::EnUS |
ja-JP | 日文 | Language::JaJP |
ko-KR | 韩文 | Language::KoKR |
vi-VN | 越南文 | Language::ViVN |
chart = astro.by_solar("2000-8-16", 2, "female", language="en-US")chart, _ := iztro.BySolar("2000-8-16", 2, iztro.GenderFemale, true, iztro.LanguageJaJP, nil)by_solar("2000-8-16", 2, Gender::Female, true, Language::KoKR, Config::default())?;哪些内容会翻译
会翻译的是所有面向人阅读的文本:
- 星耀名、宫位名、四化名、亮度名
- 天干、地支、五行局
- 时辰名与时间段、星座、生肖、性别
- 农历日期的中文表示、干支纪日展示串
- 运限层级名(大限 / 流年 / …)
不翻译的是所有标识字段与数值字段:星耀的 key、宫位的 nameKey、
宫位索引、大限区间、虚岁等。见 key 契约。
非中文译名的三个坑
- 英文与韩文没有亮度译名,输出的是记号:
[+3](庙)、[+2](旺)、[+1](得)、[0](利)、[-1](平)、[-2](不)、[-3](陷)。 繁体、日文、越南文有真译名。 - 英文四化输出
A/B/C/D,依次是禄、权、科、忌。 - 非中文译名沿用 iztro 的词表,不保证是该语言命理界的通行译法,
个别条目还是误译 —— 例如韩文把「来因宫」译成
라인(line 的音译)。 译名只做展示,判断一律用标识字段。
换盘面语言不改变排盘结果
盘面语言只影响翻译层。同一个生日在六种盘面语言下:
- 十二宫的位置与宫名顺序完全相同
- 每个宫里的星耀完全相同
- 四化、亮度、大限小限、运限干支完全相同
变的只是这些东西被写成什么字。所以下面两张盘除文本外逐字段相等:
zh = astro.by_solar("2000-8-16", 2, "female", language="zh-CN")
en = astro.by_solar("2000-8-16", 2, "female", language="en-US")
assert zh.palace(PalaceName.SOUL).index == en.palace(PalaceName.SOUL).index
assert zh.soul_key == en.soul_key六种盘面语言的一致性由变体金标测试覆盖,零容忍差异。
标识与译名的换算
手上只有标识(或只有某种语言的译名)时,用双向查找函数换算,不必重新排盘:
translate_key("ziweiMaj", Language::EnUS); // Some("emperor")
key_of("emperor"); // Some("ziweiMaj")
key_of("자미"); // Some("ziweiMaj")类别已知时用强类型版本更直接,也免去 Option:
use x_iztro::{translate_palace, translate_star};
translate_star(StarKey::ZiweiMaj, Language::ViVN); // Tử Vi
translate_palace(Palace::Soul, Language::KoKR); // 명궁覆盖十二类共 260 个标识:星耀、宫位(含身宫、来因宫)、天干、地支、亮度、四化、 五行局、性别、生肖、时辰、星座、运限层级。完整清单与逐条说明见 Rust、Python、Go 三页。
反查查不到时返回空,不是原样返回
key_of("不存在的名字") 返回 None / 空串,而不是把入参吐回来。
另有同形译名的问题:不同标识在某些语言下译名相同(horse、dragon、유시 等)。
反查按固定的扫描顺序取第一个命中,与 iztro 的 kot 逐例一致。
要指定类别就用 key_of_in(Rust)/ key_of(text, key_filter)(Python)/
KeyOfIn(Go),传标识名的共同后缀消歧:
"Maj" 只看十四主星、"Min" 只看辅星、"Palace" 只看宫位、"Hour" 只看时辰。
三种编程语言的取值形态不同
| 排盘结果里存什么 | 换盘面语言的代价 | |
|---|---|---|
| Rust | 枚举(StarKey、Palace…),只有少数展示字段是 String | 调翻译函数,同一张盘可同时输出多种语言 |
| Python | 译名与标识两组字段都已经是字符串 | 重新排盘 |
| Go | 同上 | 重新排盘 |
排盘本身是毫秒级,多排几次不是问题。判断逻辑请始终用标识字段, 这样换盘面语言不需要改任何代码。
没有全局语言开关
x-iztro 不设「当前语言」这样的全局状态:排盘时语言随参数传入, 翻译函数每次调用都显式指定目标语言。
为什么
全局语言开关会让同一段代码在不同调用顺序下产出不同结果,并发环境尤其危险。 显式传参使每次调用的结果只由入参决定。
新增一种语言要改哪些地方
词表不是一个可以外挂的资源文件,是编译进库的静态表。加一种语言要动四处:
src/data/types.rs 的 Language 枚举加一个变体,并在 as_code / from_code 里补上语言代码src/i18n/ 下新增一个词表文件,实现与既有文件相同的一组函数(星名、宫名、干支名、亮度、四化……)src/i18n/mod.rs 里每个翻译函数的 match 各加一条分派 —— 这里是逐个函数的,不是一处src/i18n/lookup.rs 的 lang_index 与反查扫描顺序表加一项;反查顺序会影响同形译名落到哪个标识,须与金标对照绑定层不需要改:语言代码是字符串传入的,加了枚举变体三侧自动可用。