#swift
#swift
Вопрос:
У меня есть 2 структуры, первая из которых:
struct LineData {
init (name: String,
colorValue: String,
values: [Int]){
self.name = name
self.colorValue = colorValue
self.values = values
}
private var cachedMaxValue: Int? = nil
let name: String
let colorValue: String
let values: [Int]
// describe max value for Y axis for specific Line
mutating func maxValue() -> Int{
if let cached = cachedMaxValue {
return cached
}
self.cachedMaxValue = values.max()
return cachedMaxValue ?? 0
}
}
У второго есть массив LineData
структур:
struct CharData {
init(xAxis: XAxis,
lines: [LineData]){
self.xAxis = xAxis
self.lines = lines
}
private var cachedMaxValue: Int? = nil
var xAxis: XAxis
var lines: [LineData]
// describe max value for Y axis among lines
func maxValue() -> Int{
var maxValues: [Int] = []
lines.forEach{it in
maxValues.append(it.maxValue())
}
return 0
}
}
Приведенный выше код не компилируется из-за ошибки в методе maxValues
для struct CharData
. В нем говорится Cannot use mutating member on immutable value: 'it' is a 'let' constant
Что я хочу, так это выполнить итерацию по массиву строк и среди его максимальных значений найти большее значение.
Ответ №1:
Поскольку lines — это обычный массив, как насчет простого:
for i in 0..<lines.count {
maxValues.append(lines[i].maxValue())
}
возможно, не так быстро, но ничего не копируется. Оптимизатор должен обеспечить вам практически такую же производительность, как у forEach.
Комментарии:
1.
for i in lines.indices {
Ответ №2:
Неизменяемым является it
параметр / объект в forEach. Точно так же, как написано в ошибке: «это let». Вероятно, вы могли бы сделать что-то вроде этого:
lines.forEach { it in
var mutableIt = it
maxValues.append(mutableIt.maxValue())
}
Следует отметить, что это создаст изменяемую копию экземпляра структуры «it».
Комментарии:
1. Однако это не соответствовало бы цели кэширования. cachedMaxValue обновляется только во (временной) изменяемой копии.
2. @EvgeniyKleban Конечно, создание всех этих копий может привести к снижению производительности при работе с большими наборами данных (я предполагаю, что именно поэтому вы кэшируете значение в первую очередь). Возможно, вам было бы лучше использовать другой стиль
for
цикла вместо этого.3. @MartinR Вы абсолютно правы. Это решает исходную проблему, но с большими наборами данных могут возникнуть проблемы, связанные с производительностью. Я полагаю, зависит от конкретного варианта использования.