Swift where条件检查是否实现了属性

Swift where条件检查是否实现了属性,swift,generics,protocols,extension-methods,Swift,Generics,Protocols,Extension Methods,我刚刚找到了另一种在Swift中充分利用协议和协议扩展的方法,通过扩展可选协议来添加一个函数,这样我就可以提供默认值 我在这里写了一篇博文: 这篇文章的要点是,我需要一种干净、简单的方法为可选字符串提供默认值,该字符串为nil或空。为此,我创建了一个可清空的协议端,扩展了可选协议,如下所示: protocol Emptyable { var isEmpty: Bool { get } } extension Optional where Wrapped: Emptyable {

我刚刚找到了另一种在Swift中充分利用协议和协议扩展的方法,通过扩展可选协议来添加一个函数,这样我就可以提供默认值

我在这里写了一篇博文:

这篇文章的要点是,我需要一种干净、简单的方法为可选字符串提供默认值,该字符串为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 {}

不,如果不使用协议,则无法查询对象或值是否具有某个属性作为扩展的约束。这需要以目前Swift中未实施的方式进行反思。另外,
isEmpty
属性对于不同类型可能有不同的含义,因此测试是否存在方法或属性而不是协议可能会导致意外行为

你可以直接写

if let unwrappedString = optionalString, !unwrappedString.isEmpty {
    // Do stuff
} else {
    // Use default value
}
无需协议或扩展,可读性强

在今年秋天出版的Swift 4中,它继承了
系列
Collection
协议提供了一个
isEmpty
属性,因此您的扩展可以是

extension Optional where Wrapped: Collection {
     // ...
}

但是,即使在存储第一个空字符串时,也应该考虑将空字符串设为零,因为现在有两个状态(NIL和空),它们似乎表示完全相同的事情。

镜像不能用作扩展的约束。不管包装类型如何,为每个可选值提供方法都是非常糟糕的。当然,你是对的!正在考虑另一种设计。。。无论如何,谢谢;)“让x=y,!x.isEmpty…”正是我想要摆脱的无论如何,我已经认为不可能检查功能或属性是否存在,因此感谢您的确认。顺便说一下,我现在更进一步,把我的函数变成一个叫做???的操作符???。也许有点过头了,但这对我来说更像是一件学习的事情,而不是在实际的客户项目中使用它。嗯,在我自己的个人项目中,我可能会使用它:您的
或whennilorempty
函数真的需要通用吗?您不能将
t
替换为
Wrapped
?或者您的API设计为支持任意类型的默认值(但最后一行的强制转换可能总是成功的)?您是对的。实际上根本不需要T。谢谢你的提示!
extension Optional where Wrapped: Collection {
     // ...
}