簡體   English   中英

帶有關聯值的開關內部的快速突變

[英]Swift Mutation inside switch with associated values

我有想要變異的這些結構:

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中使用此變異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
    }
}

問題是CheckoutViewModel結構永遠不會發生突變。 我猜想該開關不是一個可變函數,因此該開關內的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功能嗎?

根據Swift編程語言

switch案例可以將其匹配的一個或多個值綁定到臨時常量或變量,以用於案例主體中。 此行為稱為值綁定,因為值綁定到案例主體內的臨時常量或變量。

更改此類臨時變量(例如, modes變量)不會影響正在打開的枚舉的內容(例如, kind )。

對於第一種工作方法,確實確實需要另一種switch語句,該語句創建對枚舉的關聯值的引用,從而允許您就地修改該值。 這樣的聲明在Swift 3.0.1中不存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM