【问题标题】:Array.reduce cannot assign through subscript: 'x' is a 'let' constantArray.reduce 不能通过下标赋值:'x' 是一个 'let' 常量
【发布时间】:2018-03-28 00:14:14
【问题描述】:

我正在尝试在数组上使用reduce函数:

var fields = ["gender", "name", "nickname"]
var stats = fields.reduce([String:String]()) { (res, field) -> [String:String] in
  res[field] = json[field] ?? ""
  return res
}

它只是通过 fields 数组并将值从 json 对象分配给 res

对我来说似乎很简单,但编译器一直在说:

错误:无法通过下标赋值:'res' 是一个 'let' 常量

上线:

res[field] = json[field] ?? ""

这对我来说没有任何意义,因为我从未将 resstats 指定为 let

【问题讨论】:

  • 当然你把 res 设为 let,它在哪里声明为 var?
  • @Lu_ 我在看这个例子stackoverflow.com/a/39791331/8643650
  • 没错,您在哪里将 ser res 作为 var?它是在示例中完成的

标签: arrays swift


【解决方案1】:

闭包参数(除非用inout 声明)是隐式常量,就像用let 声明一样。 如果要修改它,则必须先制作可变副本:

let stats = fields.reduce([String:String]()) { (res, field) -> [String:String] in
    var res = res
    res[field] = json[field] ?? ""
    return res
}

Swift 4 开始,您可以使用 reduce(into:_:)

let stats = fields.reduce(into: [String:String]()) { (res, field) in
    res[field] = json[field] ?? ""
}

这里的res 是一个“inout”参数,可以在闭包中改变。 这样效率更高,因为每个文件都没有复制 迭代步骤。

另见SE-0171 Reduce with inout


另一种 Swift 4 解决方案是创建一个新字典 通过将每个字段映射到键/值对:

let stats = Dictionary(uniqueKeysWithValues: fields.map { ($0, json[$0] ?? "") })

【讨论】:

    【解决方案2】:

    在 Swift 中,参数是不可变的,您不能更改作为参数接收的字典

    res[field] = json[field] ?? ""
    

    解决方案

    let json: [String:Any] = ...
    let fields = ["gender", "name", "nickname"]
    let stats = fields.reduce([String:String]()) { (res, field) -> [String:String] in
        var res = res
        res[field] = (json[field] as? String) ?? ""
        return res
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      • 1970-01-01
      相关资源
      最近更新 更多