使用指南

语言无关的 key 契约

为什么星名不能拿来做判断,key 字段是什么,三种编程语言各自怎么用。

适合:开发者

问题

排盘结果的文本会跟着盘面语言变。同一颗星,中文盘上是「紫微」,英文盘上是 emperor, 韩文盘上是 자미。如果判断逻辑写成:

# 反面例子
if any(s.name == "紫微" for s in soul.major_stars):
    ...

那么这段代码只在 language="zh-CN" 时正确。换成任何其他盘面语言就静默失效 —— 不会报错,只是永远返回 False。这类 bug 很难发现。

解法

每个会被翻译的字段,x-iztro 都额外提供一个语言无关标识(key)。 key 的取值是 iztro 的 i18n 键名,与盘面语言无关,永远不变。

{
  "name": "紫微",
  "key": "ziweiMaj",
  "brightness": "庙",
  "brightnessKey": "miao",
  "mutagen": "禄",
  "mutagenKey": "sihuaLu"
}

name 给人看,key 给代码用。

有哪些 key 字段

数据翻译字段标识字段取值示例
星耀namekeyziweiMaj
亮度brightnessbrightnessKeymiao
四化mutagenmutagenKeysihuaLu
宫位名namenameKeysoulPalace
天干heavenly_stemheavenlyStemKeyjiaHeavenly
地支earthly_branchearthlyBranchKeyziEarthly
五行局five_elements_classfiveElementsClassKeywater2nd
命主 / 身主soul / bodysoulKey / bodyKeyziweiMaj
性别gendergenderKeymale
长生十二神changsheng12changsheng12Keychangsheng
博士十二神boshi12boshi12Keyboshi
将前十二神jiangqian12jiangqian12Keyjiangxing
岁前十二神suiqian12suiqian12Keysuijian
宫干四化星mutagenStarKeys["taiyangMaj", …]

三种编程语言的用法

Python:枚举

x_iztro.enums 里所有枚举都是 StrEnum成员的值就是 key

from x_iztro.enums import MajorStar, Mutagen, PalaceName, Brightness

MajorStar.ZIWEI      # "ziweiMaj"
Mutagen.LU           # "sihuaLu"
PalaceName.SOUL      # "soulPalace"
Brightness.MIAO      # "miao"

判断方法接受枚举:

soul = chart.palace(PalaceName.SOUL)
soul.has([MajorStar.ZIWEI])
soul.has_mutagen(Mutagen.LU)

因为是 StrEnum,它同时也是字符串,可以直接和 key 字段比较:

star.key == MajorStar.ZIWEI   # True

Go:常量

keys.go 里的常量值就是 key:

iztro.PalaceSoul      // "soulPalace"
iztro.StarZiweiMaj    // "ziweiMaj"
iztro.MutagenLu       // "sihuaLu"
iztro.BrightnessMiao  // "miao"

soul := chart.Palace(iztro.PalaceSoul)
soul.Has(iztro.StarZiweiMaj)
star.WithMutagen(iztro.MutagenQuan)
star.WithBrightness(iztro.BrightnessMiao)

Rust:枚举本身

Rust 侧不需要 key 字段 —— 结构体里存的本来就是枚举,翻译是显示时才做的事。

if soul.has(&[StarKey::ZiweiMaj]) { }

需要 key 字符串时(例如自己做序列化)调 as_key()

Palace::Soul.as_key();        // "soulPalace"
Mutagen::Lu.as_key();         // "sihuaLu"
Brightness::Miao.as_key();    // "miao"

验证方式

同一个生日分别用六种盘面语言排盘,所有 key 字段必须逐一相等 —— 这条由绑定契约测试(golden_contract)与 Go / Python 的端到端金标测试守着。

所以下面这段代码在任何盘面语言下结果都相同:

for lang in ["zh-CN", "zh-TW", "en-US", "ja-JP", "ko-KR", "vi-VN"]:
    chart = astro.by_solar("2000-8-16", 2, "female", language=lang)
    soul = chart.palace(PalaceName.SOUL)
    assert soul.has_mutagen(Mutagen.LU) == expected

什么时候可以用文本

展示。只有展示。任何进入 if 的比较都应该用 key。

本页目录