# NonNominalTypeWrapper

{% tabs %}
{% tab title="👔 NonNominalTypeWrapper" %}
💾 程式：[paiza.io](https://paiza.io/projects/BgeXldbalSZcvt3C_5qcQg)    ⬆️ 需要： [hasmirrors](https://lochiwei.gitbook.io/ios/swift/debugging/hasmirrors "mention")

```swift
// --------------------------------
//     ⭐ NonNominalTypeWrapper
// --------------------------------

/// non-nominal type: 
/// ⛔ - can't be extended. 
/// ⛔ - can't conform to protocols.
/// use this type to wrap non-nominal types, so they can do these things.
public struct NonNominalTypeWrapper<T> {
    let subject: T     // T is non-nominal (i.e. Any, Tuple)
}

/// convenience init
/// usage: `NonNominalTypeWrapper(instance)`
extension NonNominalTypeWrapper {
    // ⭐ 注意：這裡不能寫成 init<T>
    // 不然會引進「新的型別參數 `T`」（是的，跟「舊的型別參數 `T`」
    // 名字一模一樣），然後產生「令人傻眼的錯誤訊息」：
    // 「⛔ cannot assign value of type 'T' to type 'T'」
    public init(_ subject: T){
        self.subject = subject
    }
}

/// ⭐ custom extension (Loggable conformance)
extension NonNominalTypeWrapper: Loggable {

    @discardableResult
    public func log() -> Self { 
        print(String(describing: self.subject)) 
        return self 
    }
    
    @discardableResult
    public func reflect() -> Self { 
        print(String(reflecting: self.subject))
        return self 
    }
    
    // mirror (object tree)
    @discardableResult
    public func mirror() -> Self {
        mirrorChildren(of: self.subject)
    }
}
```

{% endtab %}

{% tab title="💈範例" %}

```swift
// ----------------------------
//     ⭐ non-nominal types
// ----------------------------

// tuple
NonNominalTypeWrapper((true, 32))
    .log()                      // (true, 32)
    .reflect()                  // (true, 32)
    .mirror()
    // ------------------------------
    //     children of (true, 32)    
    // ------------------------------
    //   • .0: true (Bool)
    //   • .1: 32 (Int)
    // ------------------------------

NonNominalTypeWrapper((first: "Taylor", last: "Swift"))
    .log()              // (first: "Taylor", last: "Swift")
    .reflect()          // (first: "Taylor", last: "Swift")
    .mirror()
    // ----------------------------------------------------
    //     children of (first: "Taylor", last: "Swift")    
    // ----------------------------------------------------
    //   • first: Taylor (String)
    //   • last: Swift (String)
    // ----------------------------------------------------

NonNominalTypeWrapper((name: "Tony", "Stark"))
    .log()              // (name: "Tony", "Stark")
    .reflect()          // (name: "Tony", "Stark")
    .mirror()
    // -------------------------------------------
    //     children of (name: "Tony", "Stark")    
    // -------------------------------------------
    //   • name: Tony (String)
    //   • .1: Stark (String)
    // -------------------------------------------

// closure
let closure = { (a: Int) -> Int in a * 2 }

NonNominalTypeWrapper(closure)
    .log()              // (Function)
    .reflect()          // (Function)
    .mirror()           // no children
```

{% endtab %}

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

* [non-nominal-types](https://lochiwei.gitbook.io/ios/swift/type/category/non-nominal-types "mention")
* [mirror](https://lochiwei.gitbook.io/ios/swift/debugging/mirror "mention")
* [hasmirrors](https://lochiwei.gitbook.io/ios/swift/debugging/hasmirrors "mention") - required protocol.
  {% endtab %}
  {% endtabs %}
