Cody Harness
Cody Harness

Reputation: 1147

Errors inside enum function

I have an enum that is set up like this:

enum Calculators {

    case RECTANGLE
    case CIRCLE
    case TRIANGLE
    case TRAPEZOID
    case CUBE
    case CONE
    case SPHERE
    case CYLINDER
    case ASPHALT
    case TACK_SEAL_COAT
    case ASPHALT_YIELD
    case SIDEWALK
    case CONCRETE_DECK_SEALER
    case CHIP_SEAL
    case AGGREGATE_STOCK_PILE
    case BACKFILL
    case SALT_STOCK_PILE
    case SALT_SPREADER_CALIBRATION
    case ROAD_SALT_APPLICATION

    static let groups = [[RECTANGLE, CIRCLE, TRIANGLE, TRAPEZOID],
                       [CUBE, CONE, SPHERE, CYLINDER],
                       [ASPHALT, TACK_SEAL_COAT, ASPHALT_YIELD, SIDEWALK, CONCRETE_DECK_SEALER, CHIP_SEAL, AGGREGATE_STOCK_PILE, BACKFILL],
                       [SALT_STOCK_PILE, SALT_SPREADER_CALIBRATION, ROAD_SALT_APPLICATION]]

    func getCalculator(category: Int, row: Int) -> Calculators {
        if let calculator =  Calculators.groups[category][row] {
            return calculator
        } else {
            return Calculators.UNDEFINED
        }
    }
}

My idea is that I will pass in the category of calculator that I want, followed by the specific calculator and it will return the correct enum, all based on what row was selected in a TableView.

The problem is that I'm faced with a confusing error. This first error is on the if let calculator line. The error reads Enum case 'Some' not found in type 'Calculators'. I'm not sure why it's looking for this.

What does this error mean and how can I resove it?

Upvotes: 1

Views: 64

Answers (2)

Sameer
Sameer

Reputation: 201

Few things 1. Add UNDEFINED as one of the cases 2. You can also declare getCalculator as static method to access it like Calculators.getCalculator

In order to prevent program from crashing when indexes are out of range, I have added check which will return UNDEFINED.

enum Calculators {
    case RECTANGLE
    case CIRCLE
    case TRIANGLE
    case TRAPEZOID
    case CUBE
    case CONE
    case SPHERE
    case CYLINDER
    case ASPHALT
    case TACK_SEAL_COAT
    case ASPHALT_YIELD
    case SIDEWALK
    case CONCRETE_DECK_SEALER
    case CHIP_SEAL
    case AGGREGATE_STOCK_PILE
    case BACKFILL
    case SALT_STOCK_PILE
    case SALT_SPREADER_CALIBRATION
    case ROAD_SALT_APPLICATION
    case UNDEFINED

    static let groups = [[RECTANGLE, CIRCLE, TRIANGLE, TRAPEZOID],
                     [CUBE, CONE, SPHERE, CYLINDER],
                     [ASPHALT, TACK_SEAL_COAT, ASPHALT_YIELD, SIDEWALK, CONCRETE_DECK_SEALER, CHIP_SEAL, AGGREGATE_STOCK_PILE, BACKFILL],
                     [SALT_STOCK_PILE, SALT_SPREADER_CALIBRATION, ROAD_SALT_APPLICATION]]

func getCalculator(category: Int, row: Int) -> Calculators {
     if Calculators.groups.indices.contains(category) {
         let calculators = Calculators.groups[category]

         if calculators.indices.contains(row) {
            return calculators[row]
         }

     }
    return Calculators.UNDEFINED
 }
}

let testCalculator = Calculators.RECTANGLE
testCalculator.getCalculator(category: 7, row: 1) // Result: UNDEFINED
testCalculator.getCalculator(category: 1, row: 1) // Result: CONE

Upvotes: 1

Rob Napier
Rob Napier

Reputation: 299345

Your if let doesn't evaluate an optional (which is required). Array subscripting crashes if it's out of range. I think what you meant is:

func getCalculator(category: Int, row: Int) -> Calculators? {
    let groups = Calculators.groups
    guard groups.indices.contains(category) else { return nil }
    let calculatorCateogry = groups[category]
    guard calculatorCateogry.indices.contains(row) else { return nil }
    return calculatorCateogry[row]
}

Upvotes: 1

Related Questions