【问题标题】:How to make a function that changes the property of an instance?如何制作一个改变实例属性的函数?
【发布时间】:2021-06-08 12:26:49
【问题描述】:

我有一个协议、结构和实例+协议和类,应该改变结构的实例:

protocol Cars {

    var car: String { get set }
    var accesories: [String] { get set }
}

struct Car: Cars {

    var car: String
    var accesories: [String]
}


var carOne = Car(car: "Car One", accesories: ["accessoryOne", "accessoryTwo"])
var carTwo = Car(car: "Car Two", accesories: ["accessoryTwo"])

protocol Dealership {

    static var cars: [Car] { get set }

    static func addAccesories(add: [String])
}

接下来,在DealershipOne 中,我想创建一个func addAccesories,它将向实例属性添加一个字符串数组,我尝试这样做和其他一些方法,但我收到错误 不能对不可变值使用变异成员:“$0”是一个“让”常量。

class DealershipOne: Dealership {

    static var cars = [carOne, carTwo]

    static func addAccesories(add: [String]) {
        cars.forEach{ $0.accesories.append(contentsOf: add) } // ERROR

    }
}

我该如何解决这个问题?

【问题讨论】:

  • section 在哪里?
  • 抱歉,已修复

标签: arrays swift


【解决方案1】:

您不能向直接迭代对象添加新值。 $0 是一个 let 对象,所以你不能添加值。

使用索引和更新值的解决方案。

cars.indices.forEach{ cars[$0].accesories.append(contentsOf: add) }```

【讨论】:

  • 偏移量与索引不同。对于某些集合类型,这会崩溃,而且很容易忘记什么时候发生。我建议始终避免使用enumerated 提供的“偏移量”来下标
【解决方案2】:

forEach 循环中的匿名闭包参数 ($0) 是您尝试迭代的 cars 中汽车的不可变副本。

您可以使用 var car = $0 制作可变副本,但即使这样也无济于事,因为您将改变副本,而不是静态 cars 数组中的实际汽车。

如果您想继续使用 struct 来为您的汽车建模,那么在数组中修改这些汽车的属性的唯一方法是通过下标赋值获得一个左值(用 c++ 术语):

func add(accessories: [String]) {
    for i in cars.insides {
        cars[i].accessories += accessories
    }
}

(我还进行了一些小调整以使其更符合习惯用法,例如更改函数名称,并为数组使用 += 运算符而不是 Array.append(contentsOf:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 2013-06-14
    • 1970-01-01
    • 1970-01-01
    • 2023-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多