不能使用变异成员...因为追加?

rob*_*más 2 swift

我很困惑为什么我得到这个错误(swift 4.2.1).

// next, select only entries in range
let filteredDataOpt: [TimeSeriesEntry?] = filteredApps
    .map { data in
        let isInDate = dates.contains { date in
            guard let d = date else {
                return false
            }
            return Calendar.current.isDate(d, equalTo: data.date, toGranularity: Calendar.Component.day)
        }
        return isInDate ? timeSeriesDataFromAppData(data) : nil
    }.append(contentsOf: locationsData.map { data in
        let isInDate = dates.contains { date in
            guard let d = date else {
                return false
            }
            return Calendar.current.isDate(d, equalTo: data.date, toGranularity: Calendar.Component.day)
        }
        return isInDate ? timeSeriesDataFromLocationData(data) : nil
    })
Run Code Online (Sandbox Code Playgroud)

这产生了

不能在不可变值上使用变异成员:函数调用返回不可变值

在第三行.

但这不是:

// next, select only entries in range
let filteredDataOpt: [AppData?] = filteredByApps
    .map { data in
        let isInDate = dates.contains { date in
            guard let d = date else {
                return false
            }
            return Calendar.current.isDate(d, equalTo: data.date, toGranularity: Calendar.Component.day)
        }
        return isInDate ? data : nil
}
let filteredData: [AppData] = filteredDataOpt.compactMap { $0 }
Run Code Online (Sandbox Code Playgroud)

我的困惑源于这样一个事实:我正在操纵一个序列,append而不是先将它分配给一个常量,然后再append进行它.为什么我的序列是只读的?

编辑:显然地图总是(乍一看,至少,奇怪)返回一个常数.完整的,我的解决方案只是:

var filteredDataOpt: [TimeSeriesEntry?] = filteredApps
    .map { data in
        let isInDate = dates.contains { date in
            guard let d = date else {
                return false
            }
            return Calendar.current.isDate(d, equalTo: data.date, toGranularity: Calendar.Component.day)
        }
        return isInDate ? self.timeSeriesData(appData: data) : nil
}
filteredDataOpt.append(contentsOf: self.locationsData.map { data in
    let isInDate = dates.contains { date in
        guard let d = date else {
            return false
        }
        return Calendar.current.isDate(d, equalTo: data.date, toGranularity: Calendar.Component.day)
    }
    return isInDate ? self.timeSeriesData(locationData: data) : nil
})
let filteredData = filteredDataOpt.compactMap { $0 }
Run Code Online (Sandbox Code Playgroud)

但是,还有其他人发现那令人不满意吗?我坚持:

  • 中间变量
  • 我需要的变量只是一个常数

Sul*_*han 5

您的问题可以减少到以下几点:

let data = [1, 2, 3]
let data2 = [4, 5, 6]

let filteredData: [Int] = data
    .map { $0 }
    .append(contentsOf: data2.map { $0 })
Run Code Online (Sandbox Code Playgroud)

解决方案是使用串联而不是append:

let data = [1, 2, 3]
let data2 = [4, 5, 6]

let filteredData: [Int] = data
    .map { $0 }
    + data2.map { $0 }
Run Code Online (Sandbox Code Playgroud)

有关解释,这类似于:

let a: Int = 0
let b = a += 1 // this is append
let c = (a + 1) += 1 // this is append with a temporary expression
Run Code Online (Sandbox Code Playgroud)

(您将添加到立即丢弃的内容中,并且不会存储该值c).

显然应该这样做

let a: Int = 0
let b = a + 1
Run Code Online (Sandbox Code Playgroud)

请注意,即使您可以append使用临时返回值,append也没有返回值,并且您的结果filteredDataOpt将被分配Void.

临时表达式为常量(不可变)的原因是为了防止您执行类似的错误.