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<Int>?
而不是一般的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:使用计算变量扩展:类型错误的主要内容,如果未能解决你的问题,请参考以下文章