[英]Swift Mutation inside switch with associated values
I have these structs I want to mutate: 我有想要变异的这些结构:
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]
}
}
I want to use this mutating func select() method inside SelectableArray, I am calling it from a chain of mutating functions (because Sections is nested inside a struct) 我想在SelectableArray中使用此变异func select()方法,我是从一系列变异函数中调用它的(因为Sections嵌套在struct中)
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
}
}
The problem is that the CheckoutViewModel struct is never mutated. 问题是CheckoutViewModel结构永远不会发生突变。 I am guessing that switch is not a mutating function, so
var modes
inside that switch is non mutable and then it does not matter if the following functions mutate anything. 我猜想该开关不是一个可变函数,因此该开关内的
var modes
是不可变的,因此以下函数是否对任何东西都无所谓。 The workaround I managed to do is this: 我设法解决的方法是这样的:
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
}
}
Do you have any oher solution to this problem? 您对此问题有其他解决方案吗? Is there any sort of
mutating switch
function that I can use? 我可以使用任何种类的
mutating switch
功能吗?
According to The Swift Programming Language : 根据Swift编程语言 :
A
switch
case can bind the value or values it matches to temporary constants or variables, for use in the body of the case.switch
案例可以将其匹配的一个或多个值绑定到临时常量或变量,以用于案例主体中。 This behavior is known as value binding, because the values are bound to temporary constants or variables within the case's body.此行为称为值绑定,因为值绑定到案例主体内的临时常量或变量。
Changes to such a temporary variable (eg the modes
variable) do not affect the contents of the enum that is being switched on (eg kind
). 更改此类临时变量(例如,
modes
变量)不会影响正在打开的枚举的内容(例如, kind
)。
For your first approach to work you would indeed need a different sort of switch statement that creates a reference to the enum's associated value, allowing you to modify that value in place. 对于第一种工作方法,确实确实需要另一种switch语句,该语句创建对枚举的关联值的引用,从而允许您就地修改该值。 Such a statement doesn't exist in Swift 3.0.1.
这样的声明在Swift 3.0.1中不存在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.