соответствие enum RawRepresentable - PullRequest
1 голос
/ 03 апреля 2019

В книге Swift пример для перечислений работает отлично

enum CompassPoint: String {
    case north, south, east, west
}

var northCom = CompassPoint.north
print (northCom)

Однако я хочу использовать сбойный инициализатор, поэтому сделал пример этого

enum WeekDay: String {
    case monday, tuesday, wednesday, thursday, friday
    init?(rawValue: Int){
        switch rawValue {
        case 0 : self = .monday
        case 1 : self = .tuesday
        case 2 : self = .wednesday
        case 3 : self = .thursday
        case 4 : self = .friday
        default : return nil
        }
    }
}

И получаю ошибку, что Weekday не соответствует RawRepresentable - хотя я считаю, что соответствие должно быть синтезировано компилятором, поэтому не понимаю, почему это не компилируется.

Что я сделал Создал похожий рабочий пример (чтобы увидеть, в чем проблема), и все же я хочу соответствовать RawRepresentable, используя enum с ошибочным инициализатором. Я не могу найти пример этого в книге Swift, в вопросах переполнения стека или в более широком Интернете.

Что я предоставил Приведенный выше полный пример с ошибкой, а также рабочий пример ожидаемого поведения.

Что бесполезно Ссылка на книгу Swift через ссылку или комментарий бесполезна, как я взял пример оттуда. Я хочу опираться на этот пример с неисправным инициализатором. Также не полезно НЕ использовать перечисление или неисправный инициализатор. Вопрос в том, чтобы использовать отказавший инициализатор с перечислением и соответствовать RawRepresentable. Это не домашняя работа, но это ограничения вопроса для моего собственного обучения, и я заинтересован в результате.

Вопрос Как я могу использовать неисправный инициализатор с перечислением, как в нерабочем примере?

Ответы [ 2 ]

3 голосов
/ 03 апреля 2019

Очевидно, что ваше определение init?(rawValue: Int) не позволяет компилятору автоматически выводить тип RawValue. Добавление псевдонима типа помогает:

enum WeekDay: String {
    typealias RawValue = String

    case monday, tuesday, wednesday, thursday, friday

    init?(rawValue: Int){
        switch rawValue {
        case 0 : self = .monday
        case 1 : self = .tuesday
        case 2 : self = .wednesday
        case 3 : self = .thursday
        case 4 : self = .friday
        default : return nil
        }
    }
}

В качестве альтернативы определите пользовательскую функцию инициализации с другим именем параметра:

enum WeekDay: String {

    case monday, tuesday, wednesday, thursday, friday

    init?(rawInt: Int){
        switch rawInt {
        case 0 : self = .monday
        case 1 : self = .tuesday
        case 2 : self = .wednesday
        case 3 : self = .thursday
        case 4 : self = .friday
        default : return nil
        }
    }
}
1 голос
/ 03 апреля 2019

"хотя я чувствую, что соответствие должно быть синтезировано компилятором"

Да, здесь ваш rawValue имеет тип String, а не Int. Просто создайте свой enum как:

enum WeekDay: String {
    case monday, tuesday, wednesday, thursday, friday
}

А затем создайте WeekDay следующим образом:

let monday: WeekDay? = WeekDay(rawValue: "monday")
let notADay: WeekDay? = WeekDay(rawValue: "foo")

Конечно, вы также можете добавить пользовательский init, который принимает целое число в качестве аргумента:

enum WeekDay: String {
    case monday, tuesday, wednesday, thursday, friday
    init?(integer: Int){
        switch integer {
        case 0 : self = .monday
        case 1 : self = .tuesday
        case 2 : self = .wednesday
        case 3 : self = .thursday
        case 4 : self = .friday
        default : return nil
        }
    }
}

И создайте свой недельный день как:

let monday: WeekDay? = WeekDay(integer: 0)
let notADay: WeekDay? = WeekDay(integer: 30)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...