1

I have a enum like this, it contains different initial states:

enum InitialState {
    case listTableView(ListTableViewState)   
}

I want to use them like this:

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)

This is the generic function I am using:

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

I get this error of course:

Could not cast value of type 'InitialState' (0x109466da0) to 'ListTableViewState' (0x1094912b0).

How can I access it in the generic function loadInitialState?

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
PaFi
  • 888
  • 1
  • 9
  • 24

1 Answers1

2

Reason for Exception:

In the below code,

let test = inital as! T

You are casting InitialState type to T. And according to your code the type of the generic type T is ListTableViewState.

The reason T is of type ListTableViewState is derived from,

tableViewState = loadInitialState(inital: test1)

Here, tableViewState is of type ListTableViewState

This is the reason type-casting to a different type fails and throws an exception.

Solution:

You can access the associated value of an enum case using the switch statement, i.e.

func loadInitialState<T>(inital: InitialState) -> T?  {
    switch inital {
    case .listTableView(let test):
        return test as? T
    }
    return nil
}
PGDev
  • 23,751
  • 6
  • 34
  • 88
  • The default case is not needed here since there is only one case. So you could avoid it, and returning nil too. change `as?` to `as!`. `loadInitialState` would return `T` then. – ielyamani Oct 29 '18 at 13:14
  • @Carpsen90 `Default` is used because the question mentioned there can be multiple initial states. And using `as!` might result in a crash in case the type didn’t match. So the code is written for handling the edge cases. – PGDev Oct 29 '18 at 13:19
  • @PGDev While I agree that using the `as?` operator is the safer route here I think the OP would be better served if you removed the `default` clause. Given Swift `switch` exhaustive cases handling design, the OP would then need to add the missing cases down the road *explicitly* (as opposed to the current, error prone, general `default` case handling code). – Paulo Mattos Oct 29 '18 at 13:36
  • @PauloMattos Agreed. Edited the answer. – PGDev Oct 29 '18 at 14:17
  • @PGDev ...and check how the compiler feels about killing that trailing `return nil` too ;) – Paulo Mattos Oct 29 '18 at 14:29