【问题标题】:Swift Collection API: extend with a computed variable: type errorSwift Collection API:使用计算变量扩展:类型错误
【发布时间】:2021-12-22 15:30:53
【问题描述】:

我有以下方法:

private func returnNilIfEmpty<T: Collection>(_ collection: T?) -> T? {
    guard let collection = collection else { return nil }
    return collection.isEmpty ? nil : collection
}

我想扩展Collection API 以使用计算变量来提取非空值,如下所示:

extension Collection {
    var nonEmptyValue: Collection? {
        returnNilIfEmpty(self)
    }
}

但是,我收到了错误:

Protocol 'Collection' 只能用作通用约束,因为 它有 Self 或关联的类型要求

这很清楚,因为外部 Collection 可以是任何集合(例如 [Int]),而 returnNilIfEmpty 内部的集合可以是例如String

问题是如何强制执行Collection通过nonEmptyValue返回的规则和通过returnNilIfEmpty返回的相同类型的规则,以便我可以摆脱这个编译器错误?

【问题讨论】:

    标签: ios arrays swift generics swift-protocols


    【解决方案1】:

    这里用Self比较合适:

    extension Collection {
        var nonEmptyValue: Self? {
            returnNilIfEmpty(self)
        }
    }
    

    如果例如你做了Set([1,2,3]).nonEmptyValue,你希望得到一个Set&lt;Int&gt;?而不是一般的Collection?(你甚至不知道这种类型包含什么样的元素或类似的东西!),不是吗?

    【讨论】:

    • 是的,谢谢,我清楚地理解了这个问题,我只是无法弄清楚计算变量的语法(但显然,我已经为函数修复了这个问题)。我实际上想出了与您相同的解决方案(现在甚至进一步简化了它)。将您的答案标记为已接受:)
    • @RichardTopchii 哦,returnNilIfEmpty 仅用于 Collection 扩展?我只是要指出,您还可以通过执行 extension Optional where Wrapped == Collection 来实现 returnNilIfEmpty 作为 Collection? 的扩展。
    • 不是真的,我只是在试验,先想出这个功能。我什至不必写where Wrapped == Collection,我猜它已经在 Swift 中实现了,所以它也适用于可选对象
    • @RichardTopchii 实际上,忽略我刚才所说的。刚刚意识到将returnNilIfEmpty 实现为可选扩展是相当不必要的,因为它等同于可选链接:someOptionalCollection?.nonEmptyValue
    • 是的,当然,我就是这样走得更远
    【解决方案2】:

    使用Self 解决了这个问题,因为它指向集合的具体类型:

    import Foundation
    
    extension Collection {
        var nonEmptyValue: Self? {
            returnNilIfEmpty(self)
        }
    }
    
    func returnNilIfEmpty<T: Collection>(_ collection: T?) -> T? {
        guard let collection = collection else { return nil } // nil -> return nil
        return collection.isEmpty ? nil : collection // return nil if empty
    }
    
    

    进一步简化:

    import Foundation
    
    extension Collection {
        ///
        var nonEmptyValue: Self? {
            self.isEmpty ? nil : self
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-09
      • 2020-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多