问题描述
给定以下形式的通用包装器结构:
struct Observable<Base> {
var base: Base
}
如何将应用于 Observable
类型值的功能传递到内部 Base
?这可以很容易地完成,例如,使用 Equatable
协议,通过编写扩展,声明需求 func ==
并调用 Base
到 {{1} 的现有一致性},像这样:
Equatable
我怎么能对模式匹配做同样的事情,例如例如,这样我就可以直接对 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
?
解决方法
两个问题的两个结构
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,7.0]
print(collection.base) // "[1.0,7.0]\n"