emr*_*tci 7 generics swift swift-extensions option-type
我想为任何Optional类型编写扩展。
我的整数代码:
extension Optional where Wrapped == Int {
func ifNil<T>(default: T) -> T {
if self != nil {
return self as! T
}
return default
}
}
var tempInt: Int?
tempInt.ifNil(default: 2) // returns 2
tempInt = 5
tempInt.ifNil(default: 2) // returns 5
Run Code Online (Sandbox Code Playgroud)
它可以工作,但它是Optional(Int)扩展名 ( Optional where Wrapped == Int),我想将此扩展名用于任何类型Date,例如String、Double等。
您有什么建议?
您的基本问题的答案是删除该where条款:
extension Optional {
// ... the rest is the same
func isNil<T>(value: T) -> T {
if self != nil {
return self as! T
}
return value
}
}
Run Code Online (Sandbox Code Playgroud)
现在它适用于所有选项。
但这段代码很糟糕。T如果与 不同,它会崩溃Wrapped。所以你真正的意思是一个适用于的非泛型函数Wrapped:
extension Optional {
func isNil(value: Wrapped) -> Wrapped {
if self != nil {
return self! // `as!` is unnecessary
}
return value
}
}
Run Code Online (Sandbox Code Playgroud)
但这只是一种复杂的说法??(正如马特指出的)
extension Optional {
func isNil(value: Wrapped) -> Wrapped { self ?? value }
}
Run Code Online (Sandbox Code Playgroud)
除此之外,它的??威力要大得多。它包含一个自动闭包,可以避免评估默认值,除非实际使用它,并且可以throw。在大多数情况下,它也是更惯用的 Swift。您可以在 github 上找到源代码。
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T)
rethrows -> T {
switch optional {
case .some(let value):
return value
case .none:
return try defaultValue()
}
}
Run Code Online (Sandbox Code Playgroud)
但我可以想象您可能会使用基于方法的解决方案的情况(它们很奇怪,但也许存在这种情况)。您可以通过将其重写为方法来实现:
extension Optional {
public func value(or defaultValue: @autoclosure () throws -> Wrapped) rethrows -> Wrapped {
switch self {
case .some(let value):
return value
case .none:
return try defaultValue()
}
}
}
tempInt.value(or: 2)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2313 次 |
| 最近记录: |