gpt4 book ai didi

swift - 改变数组扩展与 inout 函数

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

给定一个 Color 对象数组,我希望能够根据条件将某种颜色提升到数组的顶部。假设每个 Color 都有一个 bool 值 isBright 属性,并且提升颜色的测试将是 $0.isBright。我想推广第一个这样的颜色。

我会提供一种更通用的方法来根据不同的测试来提升颜色。我已经通过两种方法成功地实现了这一点,但我不确定哪种更好。如果我错误地命名或描述了这些技术,请原谅我。

选项 A - inout 函数

private func promoteColor(from colors: inout [Color], where promote: ((Color) -> Bool)) {
if let index = colors.index(where: promote) {
let color = colors.remove(at: index)
colors.insert(color, at: 0)
}
}

// call site:
promoteColor(from: &colors, where: { $0.isBright })

选项 B - 变异数组扩展

extension Array where Element: Color {
mutating func promote(where promote: (Color) -> Bool) {
if let index = index(where: promote) {
let color = remove(at: index)
insert(color, at: 0)
}
}
}

// call site:
colors.promote(where: { $0.isBright })

我更喜欢选项 B 的可读性,但我不确定在决定使用哪一个时我还应该考虑什么。两者有什么优点或缺点吗?

编辑

我想选项 B 可以推广:

extension Array {
mutating func promote(where promote: (Element) -> Bool) {
if let index = index(where: promote) {
let element = remove(at: index)
insert(element, at: 0)
}
}
}

最佳答案

inout 应尽可能避免使用,尤其是当您具有可变函数时。

您最好的简单选择可能是:

extension Array {
mutating func promote(where predicate: (Element) -> Bool) {
if let index = index(where: predicate) {
let element = remove(at: index)
insert(element, at: 0)
}
}
}

这是我昨晚想到的另一个小更新。如果您想要更高的性能。

第二个版本将避免在提升的元素之后额外移动元素。我还测试了它,其中提升的元素是第一个元素,并且使用此逻辑是安全的。

extension Array {
mutating func promote(where predicate: (Element) -> Bool) {
if let index = index(where: predicate) {
withUnsafeMutableBufferPointer { (bufferPointer: inout UnsafeMutableBufferPointer<Element>) -> Void in
let promotedElement = bufferPointer[index]
for i in (0..<index).reversed() {
bufferPointer[i + 1] = bufferPointer[i]
}
bufferPointer[0] = promotedElement
}
}
}
}

关于swift - 改变数组扩展与 inout 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49992468/

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