我刚刚找到了另一种在 Swift 中充分利用协议和协议扩展的方法,即扩展可选协议来添加函数,以便我可以提供默认值。
我在这里写了一篇关于此的博客文章:https://janthielemann.de/random-stuff/providing-default-values-可选-string-empty-可选-string-swift-3-1/ https://janthielemann.de/random-stuff/providing-default-values-optional-string-empty-optional-string-swift-3-1/
这篇文章的要点是,我需要一种干净、简单的方法来为可选字符串(nil 或空)提供默认值。为此,我创建了一个 Emptyable 协议并扩展了可选协议,如下所示:
protocol Emptyable {
var isEmpty: Bool { get }
}
extension Optional where Wrapped: Emptyable {
func orWhenNilOrEmpty<T: Emptyable>(_ defaultValue: T) -> T {
switch(self) {
case .none:
return defaultValue
case .some(let value) where value.isEmpty:
return defaultValue
case .some(let value):
return value as! T
}
}
}
extension String: Emptyable {}
现在的问题是:有没有一种方法可以摆脱 Emptyable 协议,而是有条件检查属性或函数是否由泛型类型实现,以便我自动为每个具有以下属性的类型获取 orWhenNilOrEmpty() :isEmpty
?
UPDATE
正如 Paulo 所建议的,T 泛型实际上是不需要的,我创建了一个操作符,以便更快地访问和更方便的使用(至少我是这么认为的。请随意纠正我,我总是很乐意学习新东西并提高自己) )。
我称之为“非空零合并”运算符(谁能想出更好的名字?我觉得我在命名事物方面很糟糕:/)。希望有一天它能帮助某人:
protocol Emptyable {
var isEmpty: Bool { get }
}
infix operator ???: NilCoalescingPrecedence
extension Optional where Wrapped: Emptyable {
func orWhenNilOrEmpty(_ defaultValue: Wrapped) -> Wrapped {
switch(self) {
case .none:
return defaultValue
case .some(let value) where value.isEmpty:
return defaultValue
case .some(let value):
return value
}
}
static func ???(left: Wrapped?, right: Wrapped) -> Wrapped {
return left.orWhenNilOrEmpty(right)
}
}
extension String: Emptyable {}
extension Array: Emptyable {}
extension MyStruct: Emptyable {
let text: String
let number: Int
var isEmpty: Bool { return text.isEmpty && number == 0 }
init(text: String, number: Int) {
self.text = text
self.number = number
}
}
let mandatoryNotEmptyString = optionalOrEmptyString ??? "Default Value"
let mandatoryNotEmptyStruct = optionalOrEmptyStruct ??? MyStruct(name: "Hello World", number: 1)