Swift:为可选值创建一个中缀运算符,它在空时提供默认值
Swift: create a infix operator for Optional values which provide default values when empty
关于我的最后一个问题(在这里:),我认为我通过使用以下代码创建协议扩展来为 nil 或空字符串提供默认值非常聪明,我现在有另一个问题。但首先,这是代码:
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 协议的选项提供默认值。我这样做是为了保存这种样式的不断重复的代码(更多关于为什么我在另一个问题中提到的博客 post 中这样做):
if let unwrapped = optional, !unwrapped.isEmpty {
myLabel.text = unwrapped
} else {
myLabel.text = "Some Default Text"
}
现在为了学习和成为更好的开发人员,我认为创建一个新的运算符来为我调用 orWhenNilOrEmpty 函数会很有趣:
let optionalString: String? = nil
let actualString: String = some ??? "Hello World"
所以我尝试了这个:
infix operator ???: DefaultPrecedence
extension Optional where Wrapped: Emptyable {
static func ???<T>(left: T?, right: T) -> T {
return left.orWhenNilAndEmpty(right)
}
}
但是我得到了这个错误,我真的不明白为什么。我希望你能澄清问题并解释我做错了什么:
generic parameter 'Wrapped' could not be inferred
原来问题是试图在函数声明中使用泛型 T
。 DefaultPrecedence
也不是最佳选择。这就是我现在解决它的方法及其工作原理:
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)
}
}
现在我所要做的就是在任何我想要的地方实现 Emptyable
然后我可以使用 ???
从任何可选值中获取非空值:
extension String: Emptyable {}
let notEmptyString = nilOrEmptyOptionalString ??? "Meaningful default value"
关于我的最后一个问题(在这里:
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 协议的选项提供默认值。我这样做是为了保存这种样式的不断重复的代码(更多关于为什么我在另一个问题中提到的博客 post 中这样做):
if let unwrapped = optional, !unwrapped.isEmpty {
myLabel.text = unwrapped
} else {
myLabel.text = "Some Default Text"
}
现在为了学习和成为更好的开发人员,我认为创建一个新的运算符来为我调用 orWhenNilOrEmpty 函数会很有趣:
let optionalString: String? = nil
let actualString: String = some ??? "Hello World"
所以我尝试了这个:
infix operator ???: DefaultPrecedence
extension Optional where Wrapped: Emptyable {
static func ???<T>(left: T?, right: T) -> T {
return left.orWhenNilAndEmpty(right)
}
}
但是我得到了这个错误,我真的不明白为什么。我希望你能澄清问题并解释我做错了什么:
generic parameter 'Wrapped' could not be inferred
原来问题是试图在函数声明中使用泛型 T
。 DefaultPrecedence
也不是最佳选择。这就是我现在解决它的方法及其工作原理:
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)
}
}
现在我所要做的就是在任何我想要的地方实现 Emptyable
然后我可以使用 ???
从任何可选值中获取非空值:
extension String: Emptyable {}
let notEmptyString = nilOrEmptyOptionalString ??? "Meaningful default value"