Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enum named `Type` in nested class fails

Tags:

enums

swift

For some reason, having a nested class with an nested enum named Type dosen't play well with the swift compiler.

class A {

    class B {

        enum Type {
            case One
            case Two
        }

        let myC: Type

        init(myC: Type) {
            self.myC = myC
        }

    }

    func getB(myC: B.Type) -> B {
        return B(myC: myC) // ERROR 1
    }

}

let a = A()
let b = a.getB(.Two) // ERROR 2

The above code produces two errors: 'A.B.Type' is not convertible to 'A.B.Type' and 'A.B.Type.Type' does not have a member named 'Two'.

The following cases does work:

  • class B outside of class A
  • let b = A.B(myC: .Two)
  • enum C instead of enum Type

It this a bug in Swift or is this intended behaviour? Is Type a reserved name which we shouldn't use?

like image 621
Linus Unnebäck Avatar asked Dec 20 '22 06:12

Linus Unnebäck


2 Answers

B.Type refers to class B's metatype, which is why the compiler doesn't like you defining an inner-enum with the name 'Type'.

You can use Type in variable/constant declaration to do class reflection:

class A {

    required init() {}
}

class B {
    var a: A.Type
    var aInstance: A

    init() {
        a = A.self
        aInstance = a()
    }
}
like image 145
kellanburket Avatar answered Dec 21 '22 20:12

kellanburket


Yes, it's a reserved word. But you can go right ahead and use a reserved word as long as you mark it in backticks. This works fine:

class A {
    class B {
        enum Type {
            case One
            case Two
        }
        let myC: `Type`
        init(myC: `Type`) {
            self.myC = myC
        }
    }
    func getB(myC: B.`Type`) -> B {
        return B(myC: myC)
    }
}
like image 27
matt Avatar answered Dec 21 '22 20:12

matt