如何传递到通用包装器结构中的基值?

How to pass through to a base value in a generic wrapper struct?

给定以下形式的通用包装器结构:

struct Observable<Base> {
    var base: Base
}

如何将应用于类型 Observable 的值的功能传递给内部 Base?这可以很容易地完成,例如,使用 Equatable 协议,通过编写扩展、声明要求 func == 并直接调用 BaseEquatable 的现有一致性],像这样:

extension Observable: Equatable where Base: Equatable {
    static func == (lhs: Observable<Base>, rhs: Observable<Base>) -> Bool {
        return lhs.base == rhs.base
    }
}

我怎样才能对模式匹配做同样的事情,例如这样我就可以 switch,例如,直接在 Observable<String?> 类型的值上,就像如果它没有包含在 Observable 中我会做的那样?我想解决并看到工作的一个例子是:

enum Availability {
    case available
    case notAvailable
}

let observableDescription = Observable<Availability>(.notAvailable)

switch observableDescription {
    case .available: // …
    case .notAvailable: // …
}

奖金问题: 是否可以提供对 ExpressibleByArrayLiteral 与通用类型 Observable 的一致性,以便我可以编写 let collection: Observable<[Int]> = []

两个问题的两个结构

Expression Pattern

Equatable 实际上有 ~=(_:_:) 作为要求:

extension Observable: Equatable where Base: Equatable {
    static func == (lhs: Observable<Base>, rhs: Observable<Base>) -> Bool {
        return lhs.base == rhs.base
    }

    static func ~= (pattern: Base, value: Self) -> Bool {
        pattern ~= value.base
    }
}

现在你可以做:

let observableDescription = Observable<Availability>(base: .notAvailable)
switch observableDescription {
case .available:
    print("available")
case .notAvailable:
    print("notAvailable") // "notAvailable\n"
default:
    print("default")
}

ExpressibleByArrayLiteral

对于这个你需要一个基本数组:

struct ObservableSequence<Base>: ExpressibleByArrayLiteral where Base: Sequence {
    var base: [Base.Element]
    init(arrayLiteral elements: Base.Element...) {
        base = Array(elements)
    }
}

用法:


let emptyCollection: ObservableSequence<[Int]> = []
print(emptyCollection.base) // "[]\n"
let collection: ObservableSequence<[Double]> = [1.0, 3.0, 3.0, 7.0]
print(collection.base) // "[1.0, 3.0, 3.0, 7.0]\n"