# OptionSet

{% hint style="info" %}

* 如果變數的行為像「<mark style="color:red;">**單選題**</mark>」，可考慮用 [enum](/ios/swift/type/category/basic/enum.md)。
* 如果類似「<mark style="color:red;">**多選題**</mark>」，可考慮用 <mark style="color:orange;">**OptionSet**</mark>。
  {% endhint %}

{% tabs %}
{% tab title="⭐️ 使用" %}
{% hint style="info" %}
When creating an <mark style="color:red;">**option set**</mark>, include a <mark style="color:purple;">**`rawValue`**</mark> property in your type <mark style="color:red;">**declaration**</mark>. For your type to automatically receive <mark style="color:red;">**default implementations**</mark> for <mark style="color:red;">**set-related operations**</mark>, the <mark style="color:purple;">**`rawValue`**</mark>property must be of a type that conforms to the <mark style="color:purple;">**`FixedWidthInteger`**</mark> protocol, such as <mark style="color:purple;">**`Int`**</mark>or <mark style="color:purple;">**`UInt8`**</mark>.&#x20;
{% endhint %}

```swift
struct ShippingOptions: OptionSet {
    // ⭐️ required property
    let rawValue: Int    // ⭐️ conforms to 🅿️ FixedWidthInteger
}
```

{% hint style="info" %}
Next, create unique options as <mark style="color:red;">**static properties**</mark> of your custom type using <mark style="color:red;">**unique powers of two**</mark> (1, 2, 4, 8, 16 ...) for each individual property’s raw value so that each property can be represented by a <mark style="color:orange;">**single bit**</mark> of the type’s raw value.
{% endhint %}

```swift
struct ShippingOptions: OptionSet {

    let rawValue: Int

    // ⭐️ unit sets (containing only one element)
    static let nextDay    = ShippingOptions(rawValue: 1 << 0)
    static let secondDay  = ShippingOptions(rawValue: 1 << 1)
    static let priority   = ShippingOptions(rawValue: 1 << 2)
    static let standard   = ShippingOptions(rawValue: 1 << 3)

    // ⭐️ useful sets (containing multiple elements)
    // ⭐️ can be initialized by array literal (ExpressibleByArrayLiteral)
    static let express: ShippingOptions = [.nextDay, .secondDay]
    static let all: ShippingOptions = [.express, .priority, .standard]
}

// ⭐️ empty set
let noOptions: ShippingOptions = []
```

{% hint style="warning" %}
⭐️ 注意：**OptionSet** 的 methods 雖然看起來像是元素與集合間的用語 (源自於 [SetAlgebra](https://developer.apple.com/documentation/swift/setalgebra))，但要注意每個 OptionSet 的 <mark style="color:red;">**static properties**</mark> 本質上還是一個「集合」的概念，就算只包含一個元素都是如此！
{% endhint %}

```swift
var A: ShippingOptions = []
let B: ShippingOptions = .priority

// ⭐️ 雖然以下是集合與元素間的用語，但 A 跟 B 其實都是集合喔！
A.insert(B)
A.contains(B)
```

{% endtab %}

{% tab title="💈範例" %}
{% hint style="success" %}

* [DimensionPositions](/ios/swiftui/view/view/.dimension/dimensionpositions.md) - used by [.dimension()](/ios/swiftui/view/view/.dimension.md) to decorate views.
* [Logger](/ios/swift/debugging/logger.md) - <mark style="color:purple;">**Logger.TableOptions**</mark> is an **OptionSet**.
  {% endhint %}

#### Other examples:

```swift
let price = 87
var options: ShippingOptions = []

if price > 50 { options.insert(.priority) }
if options.contains(.priority) { ... } 
```

{% endtab %}

{% tab title="📜 協定" %}
![](/files/-MPgdZmlEpSardd2Th8C)
{% endtab %}

{% tab title="📗 參考" %}

* [x] [How to solve problems with bitwise operators in Swift](https://tanaschita.com/posts/20201214-working-with-bits-in-swift/) - Natascha Fadeeva
* [x] [Singleton (mathematics)](https://en.wikipedia.org/wiki/Singleton_\(mathematics\)) - Wikipedia
* [x] [Understanding Swift’s OptionSet](https://www.donnywals.com/understanding-swifts-optionset/) - Donny Wals
* [x] [OptionSet](https://nshipster.com/optionset/) - NSHipster
* [x] [Swift, more elegant code: OptionSet](https://medium.com/@ahmadfayyas/swift-more-elegant-code-optionset-205e4866b4aa) - Ahmad Fayyas
  {% endtab %}

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

* Swift  ⟩  Standard Libary  ⟩  [Collections](https://developer.apple.com/documentation/swift/swift_standard_library/collections)  ⟩ &#x20;
  * [OptionSet](https://developer.apple.com/documentation/swift/optionset)
  * [SetAlgebra](https://developer.apple.com/documentation/swift/setalgebra)
    {% endtab %}

{% tab title="👥 相關" %}

* [.dimension()](/ios/swiftui/view/view/.dimension.md) - use **OptionSet** to help **decorate** views.
  {% endtab %}
  {% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://lochiwei.gitbook.io/ios/swift/collections/optionset.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
