# 宫位对象 (/zh/docs/rust/palace)

PalaceData 的字段，以及星耀判断、空宫判断与飞星族的全部方法。



宫位是斗数分析的主战场。数据本身是 `PalaceData`，`chart.palace(...)` 返回的是
`PalaceRef`——同一份数据外加一个指回星盘的引用。

|      | `PalaceData`                                            | `PalaceRef<'a>`                                                           |
| ---- | ------------------------------------------------------- | ------------------------------------------------------------------------- |
| 从哪来  | `chart.palaces[i]`、`sp.target` 等字段                      | `chart.palace(...)`、`star.palace()`、`sp` 之外的查询入口                          |
| 字段   | 全部                                                      | 经 `Deref` 全部可读，`data()` 取到底层                                              |
| 判断方法 | `has` / `is_empty` / `flies_to` 一族（目标宫要传 `&PalaceData`） | 同名方法，目标宫可直接写索引或宫名                                                         |
| 独有   | —                                                       | `opposite_palace` / `surrounded_palaces` / `mutaged_places` / `astrolabe` |

本页条目按 `PalaceRef` 的形式给签名；`PalaceData` 上的同名方法只差在飞星族的
目标宫参数类型（`&PalaceData` 而非 `impl Into<PalaceTarget>`）。

```rust
let soul = chart.palace(Palace::Soul).unwrap();

soul.name;                  // 经 Deref 直接取字段
soul.opposite_palace();     // 视图独有
```

<Callout type="info">
  本页示例统一用 `Language::ZhCN` 排盘，因此输出里的展示值都是中文。
  `name` 等枚举字段本身与语言无关，展示时才经 `translate_*` 转成文本。
</Callout>

## 字段 [#字段]

| 字段                   | 类型                            | 说明                            |
| -------------------- | ----------------------------- | ----------------------------- |
| `index`              | `usize`                       | 宫位索引 0–11，0 为寅宫               |
| `name`               | `Palace`                      | 宫名                            |
| `is_body_palace`     | `bool`                        | 是否身宫                          |
| `is_original_palace` | `bool`                        | 是否来因宫（宫干与年干相同且不在子丑二宫）         |
| `heavenly_stem`      | `HeavenlyStem`                | 宫干，决定本宫飞出的四化                  |
| `earthly_branch`     | `EarthlyBranch`               | 宫支，由索引固定：0 为寅、11 为丑           |
| `major_stars`        | `Vec<Star>`                   | 十四主星中落在本宫的，按安放顺序              |
| `minor_stars`        | `Vec<Star>`                   | 十四辅星中落在本宫的                    |
| `adjective_stars`    | `Vec<Star>`                   | 杂耀                            |
| `changsheng12`       | `StarKey`                     | 长生十二神，每宫恰好一个                  |
| `boshi12`            | `StarKey`                     | 博士十二神                         |
| `jiangqian12`        | `StarKey`                     | 将前十二神                         |
| `suiqian12`          | `StarKey`                     | 岁前十二神                         |
| `decadal`            | `Decadal`                     | 大限：岁数区间与宫干支                   |
| `ages`               | `Vec<u32>`                    | 小限经过本宫的虚岁列表                   |
| `overrides`          | `Option<Arc<TableOverrides>>` | 排盘时生效的自定义四化与亮度表；未自定义时为 `None` |

<Callout type="info" title="四组十二神与三组星耀的区别">
  主星、辅星、杂耀是**列表**，一宫可以有零到多颗。
  长生、博士、将前、岁前十二神是**每宫恰好一个**的标记，十二宫刚好排满一轮，
  因此是单值字段而不是列表。
</Callout>

<Callout type="info" title="overrides 是输入不是结果">
  `overrides` 携带的是排盘配置里的自定义表——飞星族方法要按宫干查四化，
  自定义表可能改写了某个天干的四化，因此宫位得随身带着它。
  它不参与序列化，DTO 与 JSON 输出里都没有这一项。
</Callout>

***

## has / not\_have / has\_one\_of [#has--not_have--has_one_of]

**用途**　判断本宫坐了哪些星。

**斗数含义**　星耀落宫是斗数的基本盘面信息。「命宫坐紫微天相」即
`has(&[ZiweiMaj, TianxiangMaj])`。查找范围覆盖主星、辅星、杂耀三组。

**签名**

```rust
pub fn has(&self, stars: &[StarKey]) -> bool
pub fn not_have(&self, stars: &[StarKey]) -> bool
pub fn has_one_of(&self, stars: &[StarKey]) -> bool
```

**参数**

| 参数      | 类型           | 必填 | 默认 | 说明     |
| ------- | ------------ | -- | -- | ------ |
| `stars` | `&[StarKey]` | 是  | —  | 星耀标识列表 |

**返回值**

| 方法           | 语义         |
| ------------ | ---------- |
| `has`        | 列表中每一颗都在本宫 |
| `not_have`   | 列表中一颗都不在本宫 |
| `has_one_of` | 列表中至少一颗在本宫 |

**示例**

```rust
use x_iztro::StarKey::*;

let soul = chart.palace(Palace::Soul).unwrap();

println!("{}", soul.has(&[ZiweiMaj, TianxiangMaj]));
println!("{}", soul.has_one_of(&[QishaMaj, ZiweiMaj]));
println!("{}", soul.not_have(&[HuoxingMin, LingxingMin]));
```

**输出**

```text
false
true
true
```

这张盘的命宫只坐紫微，天相落在财帛宫，因此要求两颗都在的 `has` 为 `false`。

**边界与陷阱**

<Callout type="warn">
  空列表下 `has` 与 `not_have` 返回 `true`，`has_one_of` 返回 `false`。
</Callout>

***

## has\_mutagen / not\_have\_mutagen [#has_mutagen--not_have_mutagen]

**用途**　判断本宫有没有某种四化。

**斗数含义**　本命四化由**生年干**决定，标记打在对应的星上。
一宫「有化禄」意味着这宫里坐着的某颗星被生年干化了禄。
注意这与飞星不同——飞星看的是宫干，本处看的是星上已有的标记。

**签名**

```rust
pub fn has_mutagen(&self, mutagen: Mutagen) -> bool
pub fn not_have_mutagen(&self, mutagen: Mutagen) -> bool
```

**参数**

| 参数        | 类型        | 必填 | 默认 | 说明                             |
| --------- | --------- | -- | -- | ------------------------------ |
| `mutagen` | `Mutagen` | 是  | —  | `Lu` / `Quan` / `Ke` / `Ji` 之一 |

**返回值**　`bool`。只扫描 `major_stars` 与 `minor_stars`，**不看杂耀**。

**示例**

```rust
let children = chart.palace(Palace::Children).unwrap();

println!("子女宫有化禄: {}", children.has_mutagen(Mutagen::Lu));
println!("子女宫无化忌: {}", children.not_have_mutagen(Mutagen::Ji));
```

**输出**

```text
子女宫有化禄: true
子女宫无化忌: true
```

**边界与陷阱**

<Callout type="warn" title="不扫杂耀">
  `has_mutagen` 只看主星与辅星上的四化标记，杂耀即使带标记也不计入
  （复刻 iztro 的行为）。要连杂耀一起看，自己遍历 `adjective_stars` 的 `mutagen` 字段。
  生年四化只会落在十四主星与部分辅星上，因此实际盘面上两种口径通常没有差别。
</Callout>

***

## is\_empty / is\_empty\_excluding [#is_empty--is_empty_excluding]

**用途**　判断本宫是否空宫。

**斗数含义**　「空宫」指没有十四主星坐守的宫。空宫要借对宫主星来看，
是斗数里一个很常见的判断分支。辅星与杂耀默认不影响空宫的成立。

**签名**

```rust
pub fn is_empty(&self) -> bool
pub fn is_empty_excluding(&self, exclude_stars: &[StarKey]) -> bool
```

**参数**

| 参数              | 类型           | 必填 | 默认 | 说明                                 |
| --------------- | ------------ | -- | -- | ---------------------------------- |
| `exclude_stars` | `&[StarKey]` | 是  | —  | 追加计入的星耀：本宫无主星、但坐了其中任一颗时，同样**不算**空宫 |

**返回值**　`bool`。判定顺序是：先看有无主星，有则不空；再看 `exclude_stars`，命中则不空；都不满足才是空宫。

**示例**

```rust
let parents = chart.palace(Palace::Parents).unwrap();
println!("父母宫空宫: {}", parents.is_empty());

let friends = chart.palace(Palace::Friends).unwrap();
println!("仆役宫空宫: {}", friends.is_empty());

// 父母宫无主星，但坐了陀罗——把陀罗也计入后就不算空宫
println!("父母宫计入陀罗后: {}", parents.is_empty_excluding(&[StarKey::TuoluoMin]));
```

**输出**

```text
父母宫空宫: true
仆役宫空宫: false
父母宫计入陀罗后: false
```

这张盘只有父母、田宅两宫无主星。仆役宫坐太阴，因此不算空宫。

**边界与陷阱**

<Accordions>
  <Accordion title="参数名容易读反">
    `exclude_stars` 不是「判断时忽略这些星」，而是「这些星也算数」。
    本宫已有主星时它完全不起作用——有主星就直接不是空宫，不再看这个列表。
  </Accordion>

  <Accordion title="只看主星">
    `is_empty` 只检查 `major_stars`。一宫辅星杂耀满座但没有主星，仍然是空宫。
    要把某些辅星也当作「填实」，把它们传进 `is_empty_excluding`。
  </Accordion>
</Accordions>

***

## flies\_to / flies\_one\_of\_to / not\_fly\_to [#flies_to--flies_one_of_to--not_fly_to]

**用途**　判断本宫宫干的四化是否飞入目标宫。

**斗数含义**　飞星派的核心手法。每个宫位有自己的宫干，宫干按四化表决定
哪四颗星化禄、权、科、忌。若被化的那颗星恰好坐在目标宫，就叫「本宫化 X 入目标宫」。
「命宫化禄入财帛」表达的是命宫这件事的顺遂落在财帛上。

**签名**

```rust
pub fn flies_to(&self, target: impl Into<PalaceTarget>, mutagens: &[Mutagen]) -> bool
pub fn flies_one_of_to(&self, target: impl Into<PalaceTarget>, mutagens: &[Mutagen]) -> bool
pub fn not_fly_to(&self, target: impl Into<PalaceTarget>, mutagens: &[Mutagen]) -> bool
```

**参数**

| 参数         | 类型                        | 必填 | 默认 | 说明                         |
| ---------- | ------------------------- | -- | -- | -------------------------- |
| `target`   | `impl Into<PalaceTarget>` | 是  | —  | 目标宫，索引 / 宫名 / 身宫 / 来因宫四种写法 |
| `mutagens` | `&[Mutagen]`              | 是  | —  | 要检查的四化                     |

**返回值**

| 方法                | 语义                 |
| ----------------- | ------------------ |
| `flies_to`        | 列出的四化**全部**飞入目标宫   |
| `flies_one_of_to` | 列出的四化**至少一个**飞入目标宫 |
| `not_fly_to`      | 列出的四化**一个都不**飞入目标宫 |

**示例**

```rust
let soul = chart.palace(Palace::Soul).unwrap();

println!("命宫化禄入财帛: {}", soul.flies_to(Palace::Wealth, &[Mutagen::Lu]));
println!("命宫化禄或忌入迁移: {}", soul.flies_one_of_to(Palace::Surface, &[Mutagen::Lu, Mutagen::Ji]));
println!("命宫不化权入子女: {}", soul.not_fly_to(Palace::Children, &[Mutagen::Quan]));
```

**输出**

```text
命宫化禄入财帛: false
命宫化禄或忌入迁移: false
命宫不化权入子女: true
```

**边界与陷阱**

<Accordions>
  <Accordion title="空的四化列表：flies_to 为假，另两个为真">
    `mutagens` 传空切片时 `flies_to` 返回 `false`，
    `flies_one_of_to` 与 `not_fly_to` 返回 `true`。

    这与「空集上全称命题为真」的直觉相反，但复刻的是 iztro 的行为：
    `flies_to` 先算出要找的星，一颗都没有就直接判假。传空通常是调用方的疏漏，
    先确认列表非空。
  </Accordion>

  <Accordion title="目标宫定位不到时三个方法都返回 false">
    目标宫写成越界索引之外的无效值时，`PalaceRef` 上的三个方法一律返回 `false`，
    包括语义上「否定」的 `not_fly_to`——定位失败不等于「没飞进去」。
    索引会先对 12 取模，因此写 `12`、`-1` 这类值不算定位失败。
  </Accordion>

  <Accordion title="自定义四化表会改变结果">
    `Config::with_mutagens` 换掉某个天干的四化表后，宫干落在该天干的宫飞出的星随之改变。
    飞星族方法读的是排盘时生效的表，不是内置默认表。
  </Accordion>

  <Accordion title="飞入自己宫叫自化">
    目标宫写成本宫时，语义上是「自化」。此时用 `self_mutaged` 一族更直观。
  </Accordion>
</Accordions>

***

## self\_mutaged / self\_mutaged\_one\_of / not\_self\_mutaged [#self_mutaged--self_mutaged_one_of--not_self_mutaged]

**用途**　判断本宫是否自化。

**斗数含义**　自化指本宫宫干化出的星恰好就坐在本宫。
含义上是「自己把自己的能量释放掉」，与飞入他宫的定向作用不同。

**签名**

```rust
pub fn self_mutaged(&self, mutagens: &[Mutagen]) -> bool
pub fn self_mutaged_one_of(&self, mutagens: &[Mutagen]) -> bool
pub fn not_self_mutaged(&self, mutagens: &[Mutagen]) -> bool
```

**参数**

| 参数         | 类型           | 必填 | 默认 | 说明                  |
| ---------- | ------------ | -- | -- | ------------------- |
| `mutagens` | `&[Mutagen]` | 是  | —  | 要检查的四化；传空切片表示「四化全部」 |

**返回值**

| 方法                    | 语义                      |
| --------------------- | ----------------------- |
| `self_mutaged`        | 列出的四化全部自化               |
| `self_mutaged_one_of` | 列出的四化至少一个自化；列表为空时检查全部四化 |
| `not_self_mutaged`    | 列出的四化一个都不自化；列表为空时检查全部四化 |

**示例**

```rust
let career = chart.palace(Palace::Career).unwrap();

println!("官禄宫自化禄: {}", career.self_mutaged(&[Mutagen::Lu]));
println!("官禄宫自化忌: {}", career.self_mutaged(&[Mutagen::Ji]));
println!("官禄宫有任一自化: {}", career.self_mutaged_one_of(&[]));
println!("官禄宫无任何自化: {}", career.not_self_mutaged(&[]));
```

**输出**

```text
官禄宫自化禄: false
官禄宫自化忌: true
官禄宫有任一自化: true
官禄宫无任何自化: false
```

官禄宫宫干为丙，丙干化忌在廉贞，而廉贞正坐官禄宫，故成自化忌。

**边界与陷阱**

<Callout type="info" title="空列表在这三个方法里的含义不同于飞星族">
  `self_mutaged_one_of` 与 `not_self_mutaged` 把空列表解释为「全部四化」，
  而不是「空集」。`self_mutaged` 不做这层回退，空列表退化成「本宫是否包含空集」，
  恒为 `true`——与 `flies_to` 的空列表判假正好相反，别把两者的直觉混用。
</Callout>

***

## mutaged\_places / mutagen\_stars [#mutaged_places--mutagen_stars]

**用途**　取本宫宫干化出的四颗星分别落在哪些宫，或直接取那四颗星本身。

**斗数含义**　飞星分析的全景版本：不问「有没有飞到某宫」，而是一次拿到禄权科忌四个落点。

**签名**

```rust
pub fn mutaged_places(&self) -> Vec<Option<PalaceRef<'a>>>
pub fn mutagen_stars(&self, mutagens: &[Mutagen]) -> Vec<StarKey>
```

**参数**

| 参数         | 类型           | 必填 | 默认 | 说明                   |
| ---------- | ------------ | -- | -- | -------------------- |
| `mutagens` | `&[Mutagen]` | 是  | —  | 要取的四化位；同一四化重复传入会重复出现 |

**返回值**　`mutaged_places` 返回长度为 4 的 `Vec`，顺序为**禄、权、科、忌**，
某颗被化的星不在这张盘上时对应位置为 `None`。
`mutagen_stars` 返回 `Vec<StarKey>`，顺序与传入的四化一致。

**示例**

```rust
let soul = chart.palace(Palace::Soul).unwrap();

for (m, place) in ["禄", "权", "科", "忌"].iter().zip(soul.mutaged_places()) {
    match place {
        Some(p) => println!("化{m} → {}", translate_palace(p.name, Language::ZhCN)),
        None => println!("化{m} → 不在盘上"),
    }
}

println!("{:?}", soul.mutagen_stars(&[Mutagen::Lu, Mutagen::Ji]));
```

**输出**

```text
化禄 → 子女
化权 → 命宫
化科 → 官禄
化忌 → 财帛
[TianliangMaj, WuquMaj]
```

命宫宫干为壬，壬干四化为天梁化禄、紫微化权、左辅化科、武曲化忌，
四颗星分别坐在子女、命宫、官禄、财帛四宫。

<Callout>
  `mutagen_stars` 取的是「本宫宫干化出哪几颗星」，与星耀自身的
  `mutagen` 字段（生年四化）无关；后者由出生年干决定。
</Callout>

<Callout type="info" title="mutaged_places 忽略入参">
  `PalaceRef::mutaged_places` 不收参数，恒按禄、权、科、忌四位返回长度为 4 的结果。
  `PalaceData` 上的同名方法要传十二宫切片（`p.mutaged_places(&chart.palaces)`），
  返回的是 `Vec<Option<usize>>` 宫位索引而不是宫位视图。
</Callout>

***

## opposite\_palace / surrounded\_palaces [#opposite_palace--surrounded_palaces]

**用途**　取本宫的对宫与三方四正。

**斗数含义**　对宫是本宫 +6 的那一宫，两宫永远相对而看。
三方四正在对宫之外再加上 +4（官禄位）与 +8（财帛位）。

**签名**

```rust
pub fn opposite_palace(&self) -> PalaceRef<'a>
pub fn surrounded_palaces(&self) -> SurroundedPalaces<'a>
```

**返回值**　`opposite_palace` 必然存在，不返回 `Option`。
`surrounded_palaces` 见[三方四正](/zh/docs/rust/surpalaces)。

**示例**

```rust
let zh = Language::ZhCN;
let soul = chart.palace(Palace::Soul).unwrap();

println!("{} 的对宫是 {}", translate_palace(soul.name, zh),
    translate_palace(soul.opposite_palace().name, zh));
println!("三方四正见煞: {}", soul.surrounded_palaces().have_one_of(&[StarKey::HuoxingMin, StarKey::LingxingMin]));
```

**输出**

```text
命宫 的对宫是 迁移
三方四正见煞: true
```

***

## astrolabe [#astrolabe]

**用途**　从宫位回到它所属的星盘。

**签名**

```rust
pub fn astrolabe(&self) -> &'a Astrolabe
```

**返回值**　`&Astrolabe`。视图始终持有星盘，因此不返回 `Option`。

**示例**

```rust
let soul = chart.palace(Palace::Soul).unwrap();
println!("{}", translate_five_elements_class(soul.astrolabe().five_elements_class, Language::ZhCN));
```

**输出**

```text
木三局
```

***

## to\_text [#to_text]

**用途**　本宫的语义化文本，与本命盘文本中该宫的段落逐字节一致：标题行带干支、大限与身宫/来因宫标记，
事实行依次是主星（空宫写「空宫」）、辅星、杂耀、三方四正、宫干飞化、十二神、小限虚岁。

**签名**

```rust
pub fn to_text(&self) -> String
```

定义在 `PalaceRef` 上，按星盘排盘语言输出；要指定语言用自由函数
`text::palace_to_text(&palace, lang)`（收 `&PalaceRef`）。

**示例**

```rust
let soul = chart.palace(Palace::Soul).unwrap();
print!("{}", soul.to_text());
```

**输出**

```text
### 命宫 (壬午) · 大限 3-12
- 主星: 紫微(庙)
- 辅星: 文曲(陷)
- 杂耀: 凤阁, 天福, 截路, 蜚廉, 年解
- 三方四正: 对宫 迁移 · 三合 财帛, 官禄
- 宫干壬飞化: 天梁化禄→子女, 紫微化权→命宫, 左辅化科→官禄, 武曲化忌→财帛
- 十二神: 长生·衰, 博士·青龙, 岁前·丧门, 将前·灾煞
- 小限虚岁: 5, 17, 29, 41, 53, 65, 77, 89, 101, 113
```

完整格式见[语义化文本](/zh/docs/guide/guides/to-text)。

***

## to\_text\_with [#to_text_with]

**用途**　本宫事实之后紧跟该宫每颗星（主星、辅星、杂耀）的释义，写法 `**星名(亮度)化X**: 正文`，
同宫主星的组合解读 `**A × B (同宫)**: ` 排在最前；十二神不释义。

**签名**

```rust
pub fn to_text_with(&self, opts: &TextOptions) -> String
```

**参数**

| 参数     | 类型             | 必填 | 默认 | 说明                                                                                                                                     |
| ------ | -------------- | -- | -- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `opts` | `&TextOptions` | 是  | —  | 输出选项；`TextOptions::new().knowledge(pack)` 带释义，`TextOptions::default()` 与 `to_text` 等价。见 [TextOptions](/zh/docs/rust/astro#textoptions) |

定义在 `PalaceRef` 上，按星盘排盘语言输出；要指定语言用自由函数
`text::palace_to_text_with(&palace, opts, lang)`。
插入位置见[带释义的文本](/zh/docs/guide/guides/to-text#带释义的文本)。

**示例**

```rust
let pack = KnowledgePack::builtin(Language::ZhCN).unwrap();
let text = chart.palace(Palace::Soul).unwrap().to_text_with(&TextOptions::new().knowledge(pack));

for line in text.lines().filter(|l| l.starts_with("**")) {
    println!("{}", line.chars().take(14).collect::<String>());
}
```

**输出**

```text
**紫微(庙)**: 紫微星
**文曲(陷)**: 文曲星
**凤阁**: 凤阁星会增加
**天福**: 天福星可以看
**截路**: 截路星按生年
**蜚廉**: 蜚廉星充满好
**年解**: 年解星按年支
```
