# 运限对象 (/zh/docs/go/horoscope)

六个运限层级的数据结构、整层取回的三个列表，以及不必再传星盘的宫位查询方法。



运限把本命盘投影到某个时间点上。同一张盘，不同年份看到的宫位分布不同——
这正是「大限走到哪一宫」的意思。

```go
h, _ := chart.Horoscope("2025-6-1", 0)
```

`Horoscope` 持有发起它的那张本命盘，因此所有查询方法都不必再把星盘传进去。

<Callout type="info">
  本页示例统一用 `"zh-CN"` 的本命盘，因此输出里的展示值都是中文。
</Callout>

## 字段 [#字段]

| 字段                        | 类型               | 跨度  | 说明                                                          |
| ------------------------- | ---------------- | --- | ----------------------------------------------------------- |
| `SolarDate` / `LunarDate` | `string`         | —   | **目标**日期的公历串与农历中文写法。出生日期在本命盘上，用 `h.Astrolabe().SolarDate` 取 |
| `Decadal`                 | `HoroscopeScope` | 十年  | 大限。未起运的幼年期为童限                                               |
| `Age`                     | `HoroscopeScope` | 一年  | 小限。按虚岁逐年走一宫                                                 |
| `Yearly`                  | `HoroscopeScope` | 一年  | 流年。按流年干支定宫                                                  |
| `Monthly`                 | `HoroscopeScope` | 一月  | 流月                                                          |
| `Daily`                   | `HoroscopeScope` | 一日  | 流日                                                          |
| `Hourly`                  | `HoroscopeScope` | 一时辰 | 流时                                                          |

<Callout type="info" title="小限与流年的区别">
  两者都是一年一走，但起法不同：小限从生年地支起、按虚岁顺推，
  流年直接看那一年的干支落在哪一宫。两条线互相独立，斗数里通常并看。
</Callout>

### HoroscopeScope [#horoscopescope]

| 字段                                   | 类型               | 说明                                                                                                        |
| ------------------------------------ | ---------------- | --------------------------------------------------------------------------------------------------------- |
| `Index`                              | `int`            | 该层级落在哪一宫（宫位索引）                                                                                            |
| `Name`                               | `string`         | 层级显示名，按输出语言翻译                                                                                             |
| `NameKey`                            | `string`         | 层级标识：`decadal` / `childhood`（童限，未起运）/ `turn`（小限）/ `yearly` / `monthly` / `daily` / `hourly`。判断层级用它，不要比对译文 |
| `HeavenlyStem` / `HeavenlyStemKey`   | `string`         | 该层级的天干，决定它飞出的四化                                                                                           |
| `EarthlyBranch` / `EarthlyBranchKey` | `string`         | 该层级的地支                                                                                                    |
| `PalaceNames` / `PalaceNameKeys`     | `[]string`       | 以该层级所在宫为命宫重推的十二宫名，按宫位索引排列                                                                                 |
| `Mutagen` / `MutagenStarKeys`        | `[]string`       | 该层级天干引发的四化星，顺序为禄权科忌；`MutagenStarKeys` 是被化四星的星耀标识，与宫位的同名字段同义                                               |
| `Stars`                              | `[][]Star`       | 该层级的流耀分布；无流耀的层级为 `nil`                                                                                    |
| `NominalAge`                         | `int`            | 仅小限：虚岁。其余层级为 `0`                                                                                          |
| `YearlyDecStar`                      | `*YearlyDecStar` | 仅流年：岁前与将前十二神。其余层级为 &#x2A;*`nil`**                                                                         |

```go
type YearlyDecStar struct {
    Suiqian12       []string `json:"suiqian12"`        // 岁前十二神译名，按宫位索引排列
    Suiqian12Keys   []string `json:"suiqian12Keys"`    // 对应标识
    Jiangqian12     []string `json:"jiangqian12"`      // 将前十二神译名
    Jiangqian12Keys []string `json:"jiangqian12Keys"`  // 对应标识
}
```

<Callout type="info" title="六个层级共用一个类型">
  Go 侧不为小限与流年各开一个类型，而是把 `NominalAge` 与 `YearlyDecStar`
  放进共用的 `HoroscopeScope`——其余层级上这两项为零值。
  调用处因此可以写按层级参数化的通用逻辑。
</Callout>

<Callout type="warn" title="YearlyDecStar 是指针，非流年层级为 nil">
  `h.Decadal.YearlyDecStar` 是 `nil`，直接取字段会 panic。
  只有 `h.Yearly.YearlyDecStar` 非空——按层级遍历时先判空。

  ```go
  h, _ := chart.Horoscope("2025-6-1", 0)

  fmt.Println(h.Decadal.YearlyDecStar == nil, h.Yearly.YearlyDecStar != nil)
  fmt.Println(h.Yearly.YearlyDecStar.Suiqian12[:3])
  fmt.Println(h.Yearly.YearlyDecStar.Jiangqian12Keys[:3])
  fmt.Println(h.Decadal.NominalAge, h.Age.NominalAge)
  ```

  **输出**

  ```text
  true true
  [天德 吊客 病符]
  [jiesha zhaisha tiansha]
  0 26
  ```
</Callout>

### PalaceIndexByName [#palaceindexbyname]

```go
func (item *HoroscopeScope) PalaceIndexByName(nameKeyOrName string) int
```

在该层级重排后的十二宫里，按宫名标识或当前语言宫名查宫位索引；**找不到返回 -1**。

```go
h, _ := chart.Horoscope("2025-6-1", 0)

fmt.Println(h.Decadal.PalaceIndexByName(iztro.PalaceSoul))
fmt.Println(h.Decadal.PalaceIndexByName(iztro.PalaceWealth))
fmt.Println(h.Decadal.PalaceIndexByName("nosuch"))
```

**输出**

```text
2
10
-1
```

<Callout type="warn">
  返回 `-1` 而不是 `0`——`0` 是合法的宫位索引（寅宫）。
  拿它去索引 `chart.Palaces` 前务必判负。
</Callout>

**示例**

```go
h, _ := chart.Horoscope("2025-6-1", 0)

for _, item := range []iztro.HoroscopeScope{h.Decadal, h.Monthly, h.Daily, h.Hourly} {
    fmt.Printf("%s 落在宫位 %d 干支 %s%s\n",
        item.Name, item.Index, item.HeavenlyStem, item.EarthlyBranch)
}

fmt.Println("小限虚岁", h.Age.NominalAge)
fmt.Println("大限四化", h.Decadal.Mutagen)
fmt.Println("流年岁前十二神", h.Yearly.YearlyDecStar.Suiqian12[:3])
```

**输出**

```text
大限 落在宫位 2 干支 庚辰
流月 落在宫位 3 干支 壬午
流日 落在宫位 8 干支 辛丑
流时 落在宫位 8 干支 戊子
小限虚岁 26
大限四化 [太阳 武曲 太阴 天同]
流年岁前十二神 [天德 吊客 病符]
```

***

## 三个列表 [#三个列表]

`DecadalList` / `YearlyList` / `MonthlyList` 是 `*Astrolabe` 上的方法，不在运限对象上：
它们一次取回整层的运限项，省去按日期逐个调 `Horoscope` 再自己拼。
三种列表项都内嵌 `HoroscopeScope`，通用字段直接访问，各自多带该层的时间坐标：

| 类型                | 多出的字段                                    | 说明                              |
| ----------------- | ---------------------------------------- | ------------------------------- |
| `DecadalListItem` | `PalaceName` / `PalaceNameKey`: `string` | 该大限所在的本命宫名                      |
|                   | `AgeRange`: `[2]int`                     | 起止虚岁，含两端                        |
|                   | `YearRange`: `[2]int`                    | 起止农历年份，含两端                      |
| `YearlyListItem`  | `Age`: `int`                             | 该流年对应的虚岁                        |
|                   | `Year`: `int`                            | 农历年份                            |
| `MonthlyListItem` | `Age`: `int`                             | 该流月对应的虚岁                        |
|                   | `Year`: `int`                            | 农历年份                            |
|                   | `Month`: `int`                           | 农历月份，正月为 1；闰月与同号常规月的 `Month` 相同 |
|                   | `IsLeapMonth`: `bool`                    | 该项是否闰月                          |
|                   | `Part`: `string`                         | 分段标识，取 `MonthPart*` 常量          |
|                   | `DayRange`: `[2]int`                     | 该段覆盖的农历日，含两端                    |

`MonthPart*` 三个常量：`MonthPartNormal` 整月一段、`MonthPartFirst` 闰月前半、
`MonthPartSecond` 闰月后半。

三个方法都各有一个 `*Context` 变体，`ctx` 用于取消等待 wasm 实例。

<Callout type="info" title="列表里的运限按时柱地支起">
  三个列表的每一项都以**时柱地支**对应的时辰计算，而不是排盘时传入的时辰索引。
  两者只在晚子时不同：入参 12 的盘，时柱地支是子，列表按时辰 0 起运限。
</Callout>

***

## DecadalList [#decadallist]

**用途**　一次取回本盘十二个大限，按起运先后排列。

**斗数含义**　大限十年一步，从起限宫顺逆行走十二宫。
把整条线摊平看，才知道某一段人生落在哪一宫、对应哪十年。

**签名**

```go
func (a *Astrolabe) DecadalList() ([]DecadalListItem, error)
func (a *Astrolabe) DecadalListContext(ctx context.Context) ([]DecadalListItem, error)
```

**返回值**　定长 12 项，第 0 项是第一个大限。顺序按起运虚岁排，
与宫位索引顺序无关（大限顺行逆行取决于阴阳男女）。

**示例**

```go
dl, _ := chart.DecadalList()

for _, d := range dl[:3] {
    fmt.Println(d.PalaceName, d.HeavenlyStem, d.EarthlyBranch, d.AgeRange, d.YearRange)
}
fmt.Println(len(dl))
```

**输出**

```text
命宫 壬 午 [3 12] [2002 2011]
兄弟 辛 巳 [13 22] [2012 2021]
夫妻 庚 辰 [23 32] [2022 2031]
12
```

这张盘三岁起运，第一个大限落在命宫。

**边界与陷阱**

<Callout type="info" title="列表里没有童限">
  起运之前的那几年是童限，只有按具体日期查 `Horoscope` 才会出现（`NameKey` 为 `childhood`）。
  `DecadalList` 列的是十二个大限本身，每项的 `NameKey` 恒为 `decadal`。
</Callout>

***

## YearlyList / YearlyListByPalace [#yearlylist--yearlylistbypalace]

**用途**　取一个大限内的全部流年。

**斗数含义**　定了大限再逐年细看，是斗数常规的推运顺序。
一个大限十年，对应的就是这十个流年。

**签名**

```go
func (a *Astrolabe) YearlyList(ordinal int) ([]YearlyListItem, error)
func (a *Astrolabe) YearlyListByPalace(nameKey string) ([]YearlyListItem, error)
```

两者各有一个 `*Context` 变体。

**参数**

| 方法                   | 参数        | 类型       | 说明                                         |
| -------------------- | --------- | -------- | ------------------------------------------ |
| `YearlyList`         | `ordinal` | `int`    | 大限序号，0 为第一个大限；越界返回错误                       |
| `YearlyListByPalace` | `nameKey` | `string` | 该大限所在的本命宫名标识（`PalaceSoul` 等常量）；空串或未知标识返回错误 |

两种写法定位到同一个大限时结果完全相同，选哪个取决于手上已有什么。

**返回值**　10 项，按虚岁先后排列。

**示例**

```go
years, _ := chart.YearlyList(2)

for _, y := range years[:3] {
    fmt.Println(y.Age, y.Year, y.HeavenlyStem, y.EarthlyBranch, "->", y.Index)
}

byPalace, _ := chart.YearlyListByPalace(iztro.PalaceSpouse)
fmt.Println(len(years), len(byPalace))
```

**输出**

```text
23 2022 壬 寅 -> 0
24 2023 癸 卯 -> 1
25 2024 甲 辰 -> 2
10 10
```

第 2 个大限落在夫妻宫，因此这两次调用问的是同一个大限。

**边界与陷阱**

<Callout type="warn" title="没有默认大限">
  `YearlyListByPalace("")` 返回错误而不是退回某个默认大限——静默取一个默认值会把漏传
  变成看起来成功的错答案。
</Callout>

***

## MonthlyList [#monthlylist]

**用途**　取一个农历年的全部流月。

**斗数含义**　流月是流年之下的一层，逐月推移。闰月怎么算是一个流派分歧点，
因此拆不拆由调用方定。

**签名**

```go
func (a *Astrolabe) MonthlyList(lunarYear int, fixLeap *bool) ([]MonthlyListItem, error)
func (a *Astrolabe) MonthlyListContext(ctx context.Context, lunarYear int, fixLeap *bool) ([]MonthlyListItem, error)
```

**参数**

| 参数          | 类型      | 必填 | 默认             | 说明                                    |
| ----------- | ------- | -- | -------------- | ------------------------------------- |
| `lunarYear` | `int`   | 是  | —              | 农历年份                                  |
| `fixLeap`   | `*bool` | 是  | `nil` 即内核默认（真） | 闰月是否拆成前后半月两项；用 `iztro.Bool(false)` 关掉 |

**返回值**　长度取决于该年有无闰月与 `fixLeap`：

| 该农历年 | `fixLeap`            | 项数 | 闰月怎么排                                                    |
| ---- | -------------------- | -- | -------------------------------------------------------- |
| 无闰月  | 任意                   | 12 | —                                                        |
| 有闰月  | `nil` 或 `Bool(true)` | 14 | 闰月拆成 `MonthPartFirst`（初一至十五）与 `MonthPartSecond`（十六至月末）两项 |
| 有闰月  | `Bool(false)`        | 13 | 闰月整月一项，`Part` 为 `MonthPartNormal`                        |

闰月排在同月号的常规月之后。每项按该段首日算出（后半段取十六）。

**示例**

```go
months, _ := chart.MonthlyList(2020, nil)

fmt.Println(len(months))
for _, m := range months[3:7] {
    fmt.Println(m.Month, m.IsLeapMonth, m.Part, m.DayRange, m.HeavenlyStem, m.EarthlyBranch)
}

whole, _ := chart.MonthlyList(2020, iztro.Bool(false))
plain, _ := chart.MonthlyList(2021, nil)
fmt.Println(len(whole), len(plain))
```

**输出**

```text
14
4 false normal [1 30] 辛 巳
4 true first [1 15] 辛 巳
4 true second [16 29] 壬 午
5 false normal [1 30] 壬 午
13 12
```

农历 2020 年有闰四月。拆开之后，闰四月前半与四月同干支（辛巳），后半跟五月同干支（壬午）
——这正是「闰月下半月算下一个月」的意思。农历 2021 年无闰月，恒为 12 项。

**边界与陷阱**

<Callout type="warn" title="这个 fixLeap 与排盘的 fixLeap 无关">
  排盘入口那个 `fixLeap` 决定闰月出生的人下半月按下个月安星，改的是本命盘布局；
  这里这个只决定本列表拆不拆闰月。两者可以取不同的值，互不影响。
</Callout>

<Callout type="info" title="闰月与常规月的 Month 相同">
  闰四月的 `Month` 也是 `4`，靠 `IsLeapMonth` 区分。按 `Month` 去重会把闰月弄丢。
</Callout>

***

## AgePalace [#agepalace]

**用途**　取小限当年所在的宫。

**斗数含义**　小限是逐年推移的一条线，落在哪一宫就以那宫为该年重点。

**签名**

```go
func (h *Horoscope) AgePalace() *Palace
```

**返回值**　`*Palace`——本命盘上的宫位。

**示例**

```go
h, _ := chart.Horoscope("2025-6-1", 0)
fmt.Println(h.AgePalace().Name)
```

**输出**

```text
田宅
```

***

## Palace [#palace]

**用途**　取某个运限层级下、按该层级重推的十二宫中的某一宫。

**斗数含义**　大限走到某宫后，以那一宫为「大限命宫」重排十二宫。
「大限的夫妻宫」问的就是这套重排后的宫位，与本命夫妻宫通常不是同一宫。

**签名**

```go
func (h *Horoscope) Palace(nameKeyOrName string, scope string) *Palace
```

**参数**

| 参数              | 类型       | 必填 | 默认 | 说明          |
| --------------- | -------- | -- | -- | ----------- |
| `nameKeyOrName` | `string` | 是  | —  | 要取的宫名标识或译名  |
| `scope`         | `string` | 是  | —  | 在哪个层级的十二宫里找 |

**返回值**　`*Palace`——本命盘上的宫位（同一格宫位在不同层级有不同宫名）。
层级为 `ScopeOrigin` 时即本命十二宫。查不到返回 `nil`。

**示例**

```go
h, _ := chart.Horoscope("2025-6-1", 0)

fmt.Println("大限命宫落在本命的", h.Palace(iztro.PalaceSoul, iztro.ScopeDecadal).Name)
fmt.Println("本命命宫是", h.Palace(iztro.PalaceSoul, iztro.ScopeOrigin).Name)
```

**输出**

```text
大限命宫落在本命的 夫妻
本命命宫是 命宫
```

**边界与陷阱**

<Callout type="info" title="返回的是本命盘上的那一格">
  返回的宫位对象上，`Name` 仍是**本命宫名**（例中的夫妻），因为它就是本命盘上的那一格。
  要看该格在大限层级叫什么，查 `h.Decadal.PalaceNames[index]`。
</Callout>

***

## SurroundPalaces [#surroundpalaces]

**用途**　取某个运限层级下某宫的三方四正。

**签名**

```go
func (h *Horoscope) SurroundPalaces(nameKeyOrName string, scope string) *SurroundedPalaces
```

**参数**　同 `Palace`。

**返回值**　`*SurroundedPalaces`，判断方法见[三方四正](/zh/docs/go/surpalaces)。

**示例**

```go
h, _ := chart.Horoscope("2025-6-1", 0)
sp := h.SurroundPalaces(iztro.PalaceWealth, iztro.ScopeYearly)

fmt.Println("流年财帛的三方四正以本命", sp.Target.Name, "为本宫")
```

**输出**

```text
流年财帛的三方四正以本命 疾厄 为本宫
```

***

## HasHoroscopeStars / HasOneOfHoroscopeStars / NotHaveHoroscopeStars [#hashoroscopestars--hasoneofhoroscopestars--nothavehoroscopestars]

**用途**　判断某层级某宫里有没有指定的流耀。

**斗数含义**　流耀是随运限层级产生的一组星：魁钺昌曲禄羊陀马鸾喜。
它们在不同层级有不同名字——大限层级叫运魁、运钺，流年层级叫流魁、流钺，
含义相同但作用于各自的时间跨度。

**签名**

```go
func (h *Horoscope) HasHoroscopeStars(nameKeyOrName string, scope string, stars []string) bool
func (h *Horoscope) HasOneOfHoroscopeStars(nameKeyOrName string, scope string, stars []string) bool
func (h *Horoscope) NotHaveHoroscopeStars(nameKeyOrName string, scope string, stars []string) bool
```

**参数**

| 参数              | 类型         | 必填 | 默认 | 说明              |
| --------------- | ---------- | -- | -- | --------------- |
| `nameKeyOrName` | `string`   | 是  | —  | 该层级下的宫名         |
| `scope`         | `string`   | 是  | —  | 运限层级            |
| `stars`         | `[]string` | 是  | —  | 流耀标识切片，须用该层级的名字 |

**返回值**

| 方法                       | 语义    |
| ------------------------ | ----- |
| `HasHoroscopeStars`      | 每一颗都在 |
| `HasOneOfHoroscopeStars` | 至少一颗在 |
| `NotHaveHoroscopeStars`  | 一颗都不在 |

**示例**

```go
h, _ := chart.Horoscope("2025-6-1", 0)

fmt.Println(h.HasHoroscopeStars(iztro.PalaceSoul, iztro.ScopeDecadal, []string{"yunlu"}))
fmt.Println(h.HasOneOfHoroscopeStars(iztro.PalaceSoul, iztro.ScopeDecadal, []string{"yunlu", "yunyang"}))
fmt.Println(h.NotHaveHoroscopeStars(iztro.PalaceSoul, iztro.ScopeDecadal, []string{"yuntuo"}))
```

**输出**

```text
false
false
true
```

**边界与陷阱**

<Accordions>
  <Accordion title="星耀参数是切片不是可变参数">
    这三个方法前面已有宫名与层级两个字符串参数，再用可变参数会让调用处产生歧义，
    因此星耀参数取 `[]string`。包里其余带星耀列表的方法都是可变参数。
  </Accordion>

  <Accordion title="scope 只决定查哪一宫，不决定查哪些星">
    三个方法用 `scope` + 宫名定位到本命盘上的某一格，
    但要比对的星耀集合恒为**大限流耀与流年流耀的并集**，与 `scope` 无关。

    因此 `scope` 传 `ScopeMonthly` 时，查的是「流月某宫这一格里有没有大限或流年的流耀」，
    而不是流月自己的流耀——流月、流日、流时三层的流耀不参与这里的比对。
    要按层级取流耀分布，用 `h.Monthly.Stars`，或
    [`GetHoroscopeStar`](/zh/docs/go/star#gethoroscopestar)。
  </Accordion>

  <Accordion title="流耀标识按层级区分">
    大限流耀叫 `StarYunlu`（运禄）、`StarYunyang`（运羊）……，流年流耀叫
    `StarLiulu`（流禄）、`StarLiuyang`（流羊）……，两组标识不同名。
    由于比对集合恒是这两组的并集，两组标识在任何 `scope` 下都查得到，只是落宫不同。
    各层级的标识对照见[安星模块](/zh/docs/go/star#gethoroscopestar)。
  </Accordion>
</Accordions>

***

## HasHoroscopeMutagen [#hashoroscopemutagen]

**用途**　判断某层级某宫里有没有该层级天干引发的四化。

**斗数含义**　每个运限层级有自己的天干，会像生年干一样化出四颗星。
「大限化禄落在大限财帛」这类判断问的就是这个。

**签名**

```go
func (h *Horoscope) HasHoroscopeMutagen(nameKeyOrName string, scope string, mutagenKey string) bool
```

**参数**

| 参数              | 类型       | 必填 | 默认 | 说明      |
| --------------- | -------- | -- | -- | ------- |
| `nameKeyOrName` | `string` | 是  | —  | 该层级下的宫名 |
| `scope`         | `string` | 是  | —  | 运限层级    |
| `mutagenKey`    | `string` | 是  | —  | 四化标识    |

**返回值**　`bool`。检查该层级天干化出的那颗星是否落在目标宫的主星或辅星里（不看杂耀）。

**示例**

```go
h, _ := chart.Horoscope("2025-6-1", 0)

fmt.Println(h.HasHoroscopeMutagen(iztro.PalaceSoul, iztro.ScopeDecadal, iztro.MutagenLu))
fmt.Println(h.Decadal.Mutagen)
```

**输出**

```text
false
[太阳 武曲 太阴 天同]
```

大限干为庚，庚干四化为太阳化禄、武曲化权、太阴化科、天同化忌。

**边界与陷阱**

<Callout type="warn" title="scope 为 ScopeOrigin 时恒为 false">
  本命层级没有「层级天干」这回事——生年四化已经打在星耀自身的 `MutagenKey` 上。
  `HasHoroscopeMutagen(name, iztro.ScopeOrigin, m)` 因此直接返回 `false`，
  不代表本命盘上没有这个四化。要查本命四化，用宫位的
  [`HasMutagen`](/zh/docs/go/palace#hasmutagen--nothavemutagen)。
</Callout>

***

## ScopeItem / Astrolabe [#scopeitem--astrolabe]

**用途**　按层级标识取对应的 `HoroscopeScope`，或回到本命盘。

**签名**

```go
func (h *Horoscope) ScopeItem(scope string) *HoroscopeScope
func (h *Horoscope) Astrolabe() *Astrolabe
```

**返回值**　`ScopeItem` 在层级为 `ScopeOrigin` 或未知层级时返回 `nil`——本命不是运限层级。

**示例**

```go
h, _ := chart.Horoscope("2025-6-1", 0)

fmt.Println(h.ScopeItem(iztro.ScopeDecadal).Name)
fmt.Println(h.ScopeItem(iztro.ScopeOrigin))
fmt.Println(h.Astrolabe().SolarDate)
```

**输出**

```text
大限
<nil>
2000-8-16
```

**边界与陷阱**

<Callout type="info">
  `ScopeItem` 用于写按层级参数化的通用逻辑，比一串 `switch scope` 简洁。
  返回 `nil` 时记得判空。
</Callout>

***

## ToText [#totext]

**用途**　运限的语义化文本：面向语言模型与人的完整描述。

**签名**

```go
func (h *Horoscope) ToText() (string, error)
func (h *Horoscope) ToTextContext(ctx context.Context) (string, error)
```

**返回值**　`string`——按星盘排盘语言输出的 Markdown 子集：`# 运限 <日期> (<农历>)` 标题下，
大限（未起运写童限）、小限、流年、流月、流日、流时各一个 `## ` 节，每节带该层命宫落在本命何宫、
四化（带落宫）、流耀与该层视角的格局行；大限与流年另展开十二宫表。
完整格式见[语义化文本](/zh/docs/guide/guides/to-text#五个入口)。

**示例**

```go
h, _ := chart.Horoscope("2025-1-1", 0)
text, _ := h.ToText()

fmt.Println(strings.Join(strings.Split(text, "\n")[:5], "\n"))
```

**输出**

```text
# 运限 2025-1-1 (二〇二四年腊月初二)

## 大限 · 命宫: 本命夫妻 (庚辰)
- 四化: 太阳化禄→本命子女, 武曲化权→本命财帛, 太阴化科→本命仆役, 天同化忌→本命疾厄
- 格局: 杀破狼 (命宫), 风云际会 (命宫)
```

格局命中的文本另见 `PatternsToText`（[格局判定](/zh/docs/go/patterns)）。

***

## ToTextWith [#totextwith]

**用途**　`ToText` 的文本，按 `opts` 带上知识包里的释义：每一层的表或事实行之后紧跟该层流耀的释义
与该层视角命中格局的释义，同一颗流耀、同一个格局跨层只释义一次。
本命星耀的释义不在这里，在星盘的 `ToTextWith` 里。

**签名**

```go
func (h *Horoscope) ToTextWith(opts TextOptions) (string, error)
func (h *Horoscope) ToTextWithContext(ctx context.Context, opts TextOptions) (string, error)
```

**参数**

| 参数     | 类型                                                 | 说明                                                                                                                                                       |
| ------ | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `opts` | [`TextOptions`](/zh/docs/go/knowledge#textoptions) | 输出选项。`Knowledge` 字段给释义材料来源：`BuiltinKnowledge()` 取盘语言的内嵌默认包，`KnowledgeFrom(pack)` 用给定的包；`PatternConfig` 字段给各层格局行与格局释义的判定口径；零值 `TextOptions{}` 等同 `ToText` |

释义的插入位置与去重规则见[带释义的文本](/zh/docs/guide/guides/to-text#带释义的文本)。

**示例**

```go
h, _ := chart.Horoscope("2025-1-1", 0)
plain, _ := h.ToText()
text, _ := h.ToTextWith(iztro.TextOptions{Knowledge: iztro.BuiltinKnowledge()})

fmt.Println(utf8.RuneCountInString(plain), utf8.RuneCountInString(text))
for _, l := range strings.Split(text, "\n") {
    if strings.HasPrefix(l, "## ") {
        fmt.Println(l)
    }
}
```

**输出**

```text
2457 8458
## 大限 · 命宫: 本命夫妻 (庚辰)
## 小限 · 命宫: 本命官禄 · 虚岁 25
## 流年 · 命宫: 本命夫妻 (甲辰)
## 流月 · 命宫: 本命仆役 (丁丑)
## 流日 · 命宫: 本命迁移 (庚午)
## 流时 · 命宫: 本命迁移 (丙子)
```

两份文本的 `## ` 节完全相同：释义不另起节，插在各层之后。

`BuiltinKnowledge()` 用在没有内嵌包的语言（目前只有 zh-CN 有）的盘上返回 `ErrInvalidArgument`。
