# 翻译 (/zh/docs/rust/i18n)

标识与译名的双向查找，以及按类目的翻译函数。



星盘上每个字段都同时给出译名与 `*_key` 标识，通常不必手工翻译。
这些函数用于手上只有标识（或只有某种语言的译名）、需要换算的场合。

支持六种语言：`zh-CN`、`zh-TW`、`en-US`、`ja-JP`、`ko-KR`、`vi-VN`。

***

## translate\_key [#translate_key]

**用途**　把任意标识译成指定语言。

**签名**

```rust
pub fn translate_key(key: &str, lang: Language) -> Option<&'static str>
```

**参数**

| 参数     | 类型         | 必填 | 默认 | 说明     |
| ------ | ---------- | -- | -- | ------ |
| `key`  | `&str`     | 是  | —  | 语言无关标识 |
| `lang` | `Language` | 是  | —  | 目标语言   |

覆盖十二类共 260 个标识：

| 类目          | 数量  | 例                                                         |
| ----------- | --- | --------------------------------------------------------- |
| 星耀          | 162 | `ziweiMaj`、`changsheng`、`yunlu`                           |
| 宫位（含身宫、来因宫） | 14  | `soulPalace`、`wealthPalace`、`bodyPalace`、`originalPalace` |
| 天干          | 10  | `jiaHeavenly`                                             |
| 地支          | 12  | `ziEarthly`                                               |
| 亮度          | 7   | `miao`、`wang`                                             |
| 四化          | 4   | `sihuaLu`                                                 |
| 五行局         | 5   | `water2nd`                                                |
| 性别          | 2   | `male`、`female`                                           |
| 生肖          | 12  | `rat`、`ox`                                                |
| 时辰          | 13  | `earlyRatHour`                                            |
| 星座          | 12  | `aries`                                                   |
| 运限层级        | 7   | `decadal`、`turn`                                          |

**返回值**　`Option<&'static str>`。未知标识返回 `None`。

**示例**

```rust
println!("{:?}", translate_key("ziweiMaj", Language::EnUS));
println!("{:?}", translate_key("soulPalace", Language::JaJP));
println!("{:?}", translate_key("nosuch", Language::ZhCN));
```

**输出**

```text
Some("emperor")
Some("命宮")
None
```

***

## key\_of [#key_of]

**用途**　由任意语言的译名反查标识。

**签名**

```rust
pub fn key_of(text: &str) -> Option<&'static str>
pub fn key_of_in(text: &str, key_filter: &str) -> Option<&'static str>
```

**参数**

| 参数           | 类型     | 必填 | 默认 | 说明                  |
| ------------ | ------ | -- | -- | ------------------- |
| `text`       | `&str` | 是  | —  | 任一支持语言下的译名          |
| `key_filter` | `&str` | 是  | —  | 限定标识名须含的子串，用于消歧同形译名 |

**返回值**　`Option<&'static str>`。查不到返回 `None`。

**示例**

```rust
println!("{:?}", key_of("紫微"));
println!("{:?}", key_of("emperor"));
println!("{:?}", key_of("자미"));
println!("{:?}", key_of("查无此名"));
```

**输出**

```text
Some("ziweiMaj")
Some("ziweiMaj")
Some("ziweiMaj")
None
```

三种语言的译名都落到同一个标识。

**边界与陷阱**

<Accordions>
  <Accordion title="同形译名与 key_of_in">
    少数译名在多个类目下同形：en-US 的 `horse` 既是生肖马也是天马，
    `dragon` 既是生肖龙也是青龙，ko-KR 的 `사` 既是地支巳也是长生12神的死。

    `key_of` 逐语言、每种语言内逐标识取先命中者，顺序与 iztro 的 `kot` 完全一致
    （有金标测试逐例守着）。要指定类目就用 `key_of_in`——标识名含该子串才纳入比对：

    ```rust
    println!("{:?}", key_of("horse"));                // Some("horse")（生肖马）
    println!("{:?}", key_of_in("horse", "Min"));      // Some("tianmaMin")（天马）
    println!("{:?}", key_of("유시"));                  // Some("hourly")（流时）
    println!("{:?}", key_of_in("유시", "Hour"));       // Some("roosterHour")（酉时）
    println!("{:?}", key_of_in("horse", "Palace"));   // None
    ```

    常用子串：`Maj` 十四主星、`Min` 辅星、`Heavenly` / `Earthly` 干支、
    `Palace` 宫位、`Hour` 时辰。限定后无匹配返回 `None`，不退回未限定的结果。
  </Accordion>

  <Accordion title="全表扫描">
    `key_of` 会遍历 260 个标识 × 6 种语言。单次调用开销可忽略，
    但不要放在每宫每星的内层循环里——那种场合直接用数据自带的 `*_key` 字段。
  </Accordion>
</Accordions>

***

## all\_keys [#all_keys]

**用途**　取全部 260 个可翻译标识。

**签名**

```rust
pub fn all_keys() -> Vec<&'static str>
```

**返回值**　`Vec<&'static str>`，顺序即 `key_of` 的反查次序：
运限层级、生肖、时辰、星座、五行局、天干、地支、亮度、四化、星耀、宫位、性别，
与 iztro 各语言翻译文件的合并次序一致。

**示例**

```rust
use x_iztro::i18n::lookup::{all_keys, translate_key};

let keys = all_keys();
println!("{} 个标识", keys.len());
println!("{:?}", &keys[..4]);
println!("{:?}", translate_key(keys[0], Language::ZhCN));
```

**输出**

```text
260 个标识
["decadal", "childhood", "yearly", "monthly"]
Some("大限")
```

要遍历某一类目自己的标识时，直接用 `data` 模块的对应常量
（`ALL_STARS`、`PALACES`、`HEAVENLY_STEMS`、`MUTAGEN` 等）更省事。

***

## 按类目的翻译函数 [#按类目的翻译函数]

标识的类别已知时，用对应的强类型函数更直接，也免去 `Option`。

| 函数                              | 入参                     |
| ------------------------------- | ---------------------- |
| `translate_star`                | `StarKey`              |
| `translate_palace`              | `Palace`               |
| `translate_heavenly_stem`       | `HeavenlyStem`         |
| `translate_earthly_branch`      | `EarthlyBranch`        |
| `translate_brightness`          | `Brightness`           |
| `translate_mutagen`             | `Mutagen`              |
| `translate_five_elements_class` | `FiveElementsClass`    |
| `translate_gender`              | `Gender`               |
| `translate_zodiac`              | `EarthlyBranch`        |
| `translate_time`                | `u8`（时辰索引 0–12）        |
| `translate_sign`                | `usize`（星座索引 0–11，白羊起） |
| `translate_horoscope_name`      | `HoroscopeName`        |

全部形如 `fn(值, Language) -> &'static str`，返回静态字符串不分配内存。

**示例**

```rust
use x_iztro::i18n::{translate_palace, translate_star};

println!("{}", translate_star(StarKey::ZiweiMaj, Language::ViVN));
println!("{}", translate_palace(Palace::Soul, Language::KoKR));
```

**输出**

```text
Tử Vi
명궁
```

***

## 没有全局语言开关 [#没有全局语言开关]

x-iztro 不设「当前语言」这样的全局状态：排盘时语言随参数传入，
翻译函数每次调用都显式指定目标语言。

<Callout type="info" title="为什么">
  全局语言开关会让同一段代码在不同调用顺序下产出不同结果，
  多线程环境尤其危险。显式传参使每次调用的结果只由入参决定。
</Callout>

要在一个进程里同时输出多种语言，直接排多张盘或多次调用翻译函数即可，互不干扰：

```rust
let zh = by_solar("2000-8-16", 2, Gender::Female, true, Language::ZhCN, Config::default())?;
let en = by_solar("2000-8-16", 2, Gender::Female, true, Language::EnUS, Config::default())?;

println!("{} / {}", zh.palace(Palace::Soul).unwrap().major_stars[0].name,
                    en.palace(Palace::Soul).unwrap().major_stars[0].name);
```

**输出**

```text
紫微 / emperor
```
