我有这些我想改变的结构:
public struct CheckoutViewModel {
var sections: [Section]
var total: String
public struct Section {
var title: String
var description: String
var kind: Kind
var expandState: ExpandState
enum Kind {
case products([ProductOrderViewModel])
case shippingMode(SelectableArray<ShippingMode>)
case shippingTarget(SelectableArray<ShippingKind>)
case billingAddress(SelectableArray<Address>)
case payment(SelectableArray<PaymentProvider>)
case promoCode(String?)
case legalAdvice(userAccepted: Bool)
}
}
}
struct SelectableArray<T> {
var selectedIndex: Int?
let options: [T]
init(options: [T]) {
self.options = options
self.selectedIndex = nil
}
mutating func select(atIndex: Int) throws -> T {
guard atIndex < options.count else {
throw SelectableArrayError.outOfBoundsIndex
}
selectedIndex = atIndex
return options[atIndex]
}
var selectedElement: T? {
guard let selectedIndex = selectedIndex else { return nil }
return options[selectedIndex]
}
}
我想在 SelectableArray 中使用这个变异函数 select() 方法,我从一个变异函数链中调用它(因为 Sections 嵌套在一个结构中)
extension CheckoutViewModel {
mutating func select(atIndexPath indexPath: IndexPath) {
sections[indexPath.section].select(atIndex: indexPath.row)
}
}
extension CheckoutViewModel.Section {
mutating func select(atIndex idx: Int) {
switch kind {
case .shippingMode(var modes):
do { _ = try modes.select(atIndex: idx) } catch { return }
default:
return nil
}
dump(self) // Here self hasn't changed
}
}
问题是 CheckoutViewModel 结构永远不会发生变化。我猜 switch 不是一个变异函数,所以那个 switch 里面的 var modes
是不可变的,那么下面的函数是否改变任何东西都没有关系。我设法做的解决方法是:
mutating func select(atIndex idx: Int) {
switch kind {
case .shippingMode(var modes):
do {
_ = try modes.select(atIndex: idx)
self.kind = .shippingMode(modes)
} catch { return }
default:
return
}
}
对于这个问题,你有什么其他的解决办法吗?有没有我可以使用的任何类型的 mutating switch
函数?
最佳答案
根据 The Swift Programming Language :
A
switch
case can bind the value or values it matches to temporary constants or variables, for use in the body of the case. This behavior is known as value binding, because the values are bound to temporary constants or variables within the case’s body.
对此类临时变量(例如 modes
变量)的更改不会影响正在打开的枚举的内容(例如 kind
)。
对于第一种工作方法,您确实需要一种不同类型的 switch 语句来创建对枚举关联值的引用,从而允许您就地修改该值。这样的声明在 Swift 3.0.1 中不存在。
关于ios - 具有关联值的开关内部的 Swift Mutation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40345536/