Swift Collection API:使用计算变量扩展:类型错误

Posted

技术标签:

【中文标题】Swift Collection API:使用计算变量扩展:类型错误【英文标题】:Swift Collection API: extend with a computed variable: type error 【发布时间】: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返回的相同类型的规则,以便我可以摆脱这个编译器错误?

【问题讨论】:

【参考方案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
    

【讨论】:

以上是关于Swift Collection API:使用计算变量扩展:类型错误的主要内容,如果未能解决你的问题,请参考以下文章

Expanding Collection - Swift

swift string.collection.swift

swift Collection的可选项

swift TableView和Collection扩展

Swift + Realm:如何从 collection.find 的范围内更改外部变量

如何在 Collection 视图中为每个单元格添加 edgeInsets -Swift