gpt4 book ai didi

arrays - Swift:Collection 中的类型转换输出数组,其中 Iterator.Element == Foo

转载 作者:搜寻专家 更新时间:2023-11-01 06:24:57 25 4
gpt4 key购买 nike

我有以下函数,它遍历 Foo 数组,并使用原始数组中的项目创建一个新数组,但颜色不同:

extension Collection where Iterator.Element == Foo {
public func color(colors: [NSColor]) -> [Foo] {
var result: [Foo] = []

for item in self {
for color in colors {
let newItem = Foo(name: item.name, color: color)
result.append(newItem)
}
}

return result
}
}

这行得通,但是如果我在 Foo 的子类 Bar 上使用它,它仍然返回 [Foo],而不是 [栏].

我可以这样做:

let colors: [NSColor] = // set colors
let colorArray = array.color(colors).map{ Bar($0.name, $.color)

但是每次为 Foo 的子类调用它时,我都需要记住这样做。

那么我该如何调整函数以使其也适用于 Foo 的子类?

编辑

根据下面的评论,我尝试了一个通用函数:

public func color<T>(colors: [NSColor]) -> [T] {
var result: [T] = []

for item in self {
for color in colors {
let newItem = T(name: item.name, color: color)
result.append(newItem)
}
}

return result
}

这给了我错误:

Non-nominal type 'T' does not support explicit initialization

所以我搜索了一下,发现我需要使用 init:

let newItem = T.init(name: item.name, color: color)

现在我得到这个错误:

Type 'T' has no member 'init'

FooBar 有一个 init,但这对这里没有帮助。我走在正确的轨道上吗?

编辑 2:

Martin 在下面的回答让我意识到我的代码中有一个错误:where Iterator.Element == Foo 应该是 where Iterator.Element: Foo

最佳答案

您可以用“子类约束”替换“相同类型约束”,并在实现中使用集合 Element 类型而不是 Foo:

extension Collection where Element: Foo {
func color(colors: [NSColor]) -> [Element] {
var result: [Element] = []
for item in self {
for color in colors {
let newItem = Element(name: item.name, color: color)
result.append(newItem)
}
}
return result
}
}

请注意,这需要 Foo(及其子类)具有“必需的 init”方法:

required init(name: String, color: NSColor) 

另一种选择是定义一个协议(protocol)

protocol P {
var name: String { get }
init(name: String, color: NSColor)
}

Foo(及其子类)符合并使用约束

extension Collection where Element: P 

用于扩展方法。

无论如何,更简洁的实现是

extension Collection where Element: Foo {
func color(colors: [NSColor]) -> [Element] {
return self.flatMap { item in
colors.map { Element(name: item.name, color: $0) }
}
}
}

重新编辑:作为免费的通用方法(而不是扩展方法),它类似于

func color<T: P>(items: [T], with colors: [NSColor]) -> [T] {
return items.flatMap { item in
colors.map { T(name: item.name, color: $0) }
}
}

使用上面定义的协议(protocol)。编译器需要知道可以根据项目名称和颜色创建 T 的实例。

关于arrays - Swift:Collection 中的类型转换输出数组,其中 Iterator.Element == Foo,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57938794/

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