gpt4 book ai didi

arrays - 扩展 Swift 数组以按类型过滤元素

转载 作者:可可西里 更新时间:2023-10-31 23:55:38 25 4
gpt4 key购买 nike

如何扩展 swift 数组以访问特定类型的成员?

如果一个数组包含继承自同一个父类(super class)的多个类的实例,这就是相关的。理想情况下,它会适本地执行类型检查。


一些不太行得通的想法和事情:

使用 filter(_:) 方法工作正常,但确实强制类型安全。例如:

protocol MyProtocol { }
struct TypeA: MyProtocol { }
struct TypeB: MyProtocol { }

let myStructs:[MyProtocol] = [ TypeA(), TypeA(), TypeB() ]

let filteredArray = myStructs.filter({ $0 is TypeA })

filteredArray 包含正确的值,但类型仍然是 [MyProtocol] 而不是 [TypeA]。我希望将最后一个替换为 let filteredArray = myStructs.filter({ $0 is TypeA }) as! [TypeA] 会解决这个问题,但项目因 EXEC_BAD_INSTRUCTION 而失败,我不明白。也许类型转换数组是不可能的?

理想情况下,此行为可以包含在数组扩展中。以下不编译:

extension Array {
func objectsOfType<T:Element>(type:T.Type) -> [T] {
return filter { $0 is T } as! [T]
}
}

这里似乎至少有两个问题:类型约束 T:Element 似乎不起作用。我不确定基于泛型类型添加约束的正确方法是什么。我在这里的意图是说 TElement 的子类型。此外,第 3 行存在编译时错误,但这可能只是传播相同的错误。

最佳答案

SequenceType 有一个 flatMap() 方法作为“可选过滤器”:

extension SequenceType {
/// Return an `Array` containing the non-nil results of mapping
/// `transform` over `self`.
///
/// - Complexity: O(*M* + *N*), where *M* is the length of `self`
/// and *N* is the length of the result.
@warn_unused_result
@rethrows public func flatMap<T>(@noescape transform: (Self.Generator.Element) throws -> T?) rethrows -> [T]
}

结合 matt 的建议使用 as? 而不是 is 你可以用作

let myStructs:[MyProtocol] = [ TypeA(), TypeA(), TypeB() ]
let filteredArray = myStructs.flatMap { $0 as? TypeA }

现在 filteredArray 的类型被推断为 [TypeA]

作为一种扩展方法,它会是

extension Array {
func objectsOfType<T>(type:T.Type) -> [T] {
return flatMap { $0 as? T }
}
}

let filteredArray = myStructs.objectsOfType(TypeA.self)

注意:对于 Swift >= 4.1,flatMap 替换为 compactMap

关于arrays - 扩展 Swift 数组以按类型过滤元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33112114/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com