【问题标题】:Enums associated values and generics枚举关联值和泛型
【发布时间】:2018-10-29 12:35:01
【问题描述】:

我有一个这样的枚举,它包含不同的初始状态:

enum InitialState {
    case listTableView(ListTableViewState)   
}

我想这样使用它们:

var tableViewState: ListTableViewState?

let test = ListTableViewState(group: .large, statIntervalBase: StatIntervalBaseModel(stat: "ppc", interval: "24h", base: "usd"), order: .ascending, searchParameter: "", quantityStats: .six)
let test1 = InitialState.listTableView(test)
tableViewState = loadInitialState(inital: test1)

这是我正在使用的通用函数:

func loadInitialState<T>(inital: InitialState) -> T  {
    let test = inital as! T
    print(test)
    return test
}

我当然得到这个错误:

无法将“InitialState”(0x109466da0) 类型的值转换为 'ListTableViewState' (0x1094912b0)。

如何在通用函数loadInitialState 中访问它?

【问题讨论】:

    标签: swift generics enums associated-value


    【解决方案1】:

    例外原因:

    在下面的代码中,

    let test = inital as! T
    

    您正在将InitialState 类型转换为T。根据您的代码,泛型类型T 的类型是ListTableViewState。

    T 的类型为ListTableViewState 的原因源自,

    tableViewState = loadInitialState(inital: test1)
    

    这里,tableViewState 的类型是 ListTableViewState

    这就是类型转换为不同类型失败并引发异常的原因。

    解决方案:

    您可以使用 switch statement 访问enum case 的associated value,即

    func loadInitialState<T>(inital: InitialState) -> T?  {
        switch inital {
        case .listTableView(let test):
            return test as? T
        }
        return nil
    }
    

    【讨论】:

    • 这里不需要默认情况,因为只有一种情况。所以你可以避免它,也可以返回 nil 。将as? 更改为as!。然后loadInitialState 将返回T。
    • 使用 @Carpsen90 Default 是因为提到的问题可以有多个初始状态。如果类型不匹配,使用as! 可能会导致崩溃。所以编写代码是为了处理边缘情况。
    • @PGDev 虽然我同意在这里使用as? 运算符是更安全的路线,但我认为如果您删除default 子句,OP 会得到更好的服务。鉴于 Swift switch 详尽的案例处理设计,OP 将需要在路上显式添加丢失的案例(与当前容易出错的通用 default 案例处理代码相反)。
    • @PauloMattos 同意。编辑了答案。
    • @PGDev ...并检查编译器对杀死尾随return nil 的感觉;)
    猜你喜欢
    • 1970-01-01
    • 2019-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多