> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/ios/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/ios/swift/attributes/result-builders/result-building-methods.md).

# result-building methods

[Swift](/ios/swift.md) ⟩ [Attributes](/ios/swift/attributes.md) ⟩ [Result Builders](/ios/swift/attributes/result-builders.md) ⟩

{% hint style="success" %}

```
規則：由最內層往外回溯 ⭐️
------------------------------
• 最內層   ：build Expression
• 遇到 {}  ：build Block
• 遇到 if  ：build 1st / Optional
• 遇到 else：build 2nd
• 遇到 for ：build Array
```

{% endhint %}

{% tabs %}
{% tab title="🔸 定義" %}
{% hint style="info" %}

* <mark style="color:purple;">**Expression**</mark> : type of the result builder’s <mark style="color:red;">**input**</mark>.
* <mark style="color:purple;">**Component**</mark> : type of a <mark style="color:red;">**partial result**</mark>.
* <mark style="color:purple;">**FinalResult**</mark> : type of the <mark style="color:red;">**result**</mark> that the result builder produces.
* **Expression** / **FinalResult** = <mark style="color:purple;">**Component**</mark> by default.
  {% endhint %}

```swift
@resultBuilder
struct ExampleResultBuilder {

  /// TYPE of individual statement expressions in the transformed function.
  /// (default = `Component` if `buildExpression()` not provided)
  typealias Expression = ...

  /// TYPE of a partial result
  /// (carried through all of the build methods)
  typealias Component = ...

  /// TYPE of the final returned result
  /// (default = `Component` if `buildFinalResult()` not provided)
  typealias FinalResult = ...
  
  // --------------------------
  //    ⭐️ Required Methods
  // --------------------------

  /// 🔸 build combined results from statement blocks.
  static func buildBlock(_ components: Component...) -> Component
  
  // --------------------------
  //    ⭐️ Optional Methods
  // --------------------------

  /// 🔸 translate expression (contextual type) into partial result.
  /// - If the result builder has `buildExpression(_:)` method(s), 
  ///   each expression becomes a call to one of the method(s). 
  /// - This transformation is always first.
  static func buildExpression(_ expression: Expression) -> Component

  /// 🔸 support `if`, `optional chaining`.
  static func buildOptional(_ component: Component?) -> Component

  /// 🔸 support 'if-else' / 'switch'.
  static func buildEither(first component: Component) -> Component
  static func buildEither(second component: Component) -> Component

  /// 🔸 support 'for..in'.
  static func buildArray(_ components: [Component]) -> Component

  /// 🔸 called on the partial result of an 'if #available' block 
  ///    to allow the result builder to erase type information.
  /// - happens before buildEither(first:/second:), buildOptional(_:)
  static func buildLimitedAvailability(_ component: Component) -> Component

  /// 🔸 called from the outermost block statement
  ///    to produce the final returned result.
  static func buildFinalResult(_ component: Component) -> FinalResult
}
```

{% endtab %}

{% tab title="📘 手冊" %}

* SE0289 (Result Builder) ⟩ [result-building methods](https://github.com/apple/swift-evolution/blob/main/proposals/0289-result-builders.md#result-building-methods) ⭐️ (🔸 定義)
* Swift Reference ⟩ Attributes ⟩ [Declaration Attributes](https://docs.swift.org/swift-book/ReferenceManual/Attributes.html#ID348) ⟩ <mark style="color:red;">**resultBuilder**</mark> ⭐️
  {% endtab %}

{% tab title="附註" %}
{% hint style="info" %}
An example to call<mark style="color:purple;">**`buildLimitedAvailability(_:)`**</mark> method can be found in [Swift Reference](https://docs.swift.org/swift-book/ReferenceManual/Attributes.html#ID633).
{% endhint %}
{% endtab %}

{% tab title="❓ " %}
{% hint style="info" %}
在 [Swift Reference](https://docs.swift.org/swift-book/ReferenceManual/Attributes.html#ID633) 範例中，有在 <mark style="color:green;">**result-building method**</mark> 內使用 <mark style="color:purple;">**guard let**</mark> 的情況 (如下)。所以 ⭐️ **重點二**所指的「<mark style="color:red;">**不能使用 guard**</mark>」應該不是指在這些 <mark style="color:green;">**result-building methods**</mark> 中，而是指**使用**這個 <mark style="color:red;">**result builder**</mark> 的 (closure) <mark style="color:red;">**block**</mark> 內部不能使用。
{% endhint %}

```
static func buildOptional(_ component: Component?) -> Component {
    // ⭐️ guard let
    guard let component = component else { return [] }
    return component
}
```

{% endtab %}
{% endtabs %}
