Swift 集合 API:使用计算变量扩展:类型错误
Swift Collection API: extend with a computed variable: type error
我有以下方法:
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' can only be used as a generic constraint because
it has Self or associated type requirements
这很清楚,因为外部 Collection
可以是任何集合(例如 [Int]
),而 returnNilIfEmpty
内部的集合可以是例如String
.
问题是如何执行 Collection
通过 nonEmptyValue
返回的规则和通过 returnNilIfEmpty
返回的相同类型的规则,以便我可以摆脱这个编译器错误?
使用 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
}
}
这里用Self
比较合适:
extension Collection {
var nonEmptyValue: Self? {
returnNilIfEmpty(self)
}
}
如果例如你做了 Set([1,2,3]).nonEmptyValue
,你期望得到一个 Set<Int>?
而不是一般的 Collection?
(你甚至不知道这个类型包含什么样的元素或类似的东西!),你不会吗?
我有以下方法:
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' can only be used as a generic constraint because it has Self or associated type requirements
这很清楚,因为外部 Collection
可以是任何集合(例如 [Int]
),而 returnNilIfEmpty
内部的集合可以是例如String
.
问题是如何执行 Collection
通过 nonEmptyValue
返回的规则和通过 returnNilIfEmpty
返回的相同类型的规则,以便我可以摆脱这个编译器错误?
使用 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
}
}
这里用Self
比较合适:
extension Collection {
var nonEmptyValue: Self? {
returnNilIfEmpty(self)
}
}
如果例如你做了 Set([1,2,3]).nonEmptyValue
,你期望得到一个 Set<Int>?
而不是一般的 Collection?
(你甚至不知道这个类型包含什么样的元素或类似的东西!),你不会吗?