Использование класса в качестве RawValue Enum не работает - PullRequest
0 голосов
/ 03 июля 2019

Я пытаюсь использовать свой пользовательский класс ChallengeUIElement как rawValue моего перечисления ChallengeUIElementType .

Поэтому я попробовал все, что Xcode хотел от меня, ноЯ все еще получаю сообщения об ошибках, брошенные прямо в лицоЭто начинает болеть ...

В любом случае, я последовал этому учебнику и получаю множество сообщений об ошибках, которые я не понимаю.

После поиска в Google некоторое время,Я обнаружил некоторые записи переполнения стека о классах как типах rawValue перечислений.

Однако мне все еще не удалось получить мое перечисление с работающим типом класса.

Мои ошибки: Errors

Вот мой код:

enum ChallengeUIElementType: ChallengeUIElement, CaseIterable {
    typealias RawValue = ChallengeUIElement

    case Default = "DefaultElementCell"
}

class ChallengeUIElement: Equatable, ExpressibleByStringLiteral {

    static func == (lhs: ChallengeUIElement, rhs: ChallengeUIElement) -> Bool {
        return lhs.identifier == rhs.identifier && lhs.height == rhs.height && lhs.type == rhs.type
    }

    var height: CGFloat
    var identifier: String
    var type: UICollectionViewCell.Type

    public init(stringLiteral value: String) {
        let components = value.components(separatedBy: ",")
        if components.count == 1 {
            if components[0] == "DefaultElementCell" {
                self.identifier = components[0]
                self.type = DefaultElementCell.self
                self.height = 380
            }
        }
    }

    public init(unicodeScalarLiteral value: String) {
        self.init(stringLiteral: value)
    }
    public init(extendedGraphemeClusterLiteral value: String) {
        self.init(stringLiteral: value)
    }
}

Кроме того, я не понимаю, почему я могиспользуйте RawRepresentable в качестве протокола с этим подходом , но не с этим ?

Любая помощь будет высоко оценена.

1 Ответ

1 голос
/ 03 июля 2019

Ошибки, которые вы получаете, в основном связаны с неправильным объявлением инициализаторов. На самом деле они не имеют ничего общего с созданием перечисления с необработанным значением класса.

Поскольку протокол требует инициализаторов, они должны быть помечены как required. Вам не нужно делать это, если ваш класс final. Поэтому либо пометьте класс как final, либо пометьте все инициализаторы как required.

Два удобных инициализатора должны быть помечены как convenience:

public convenience init(unicodeScalarLiteral value: String) {
    self.init(stringLiteral: value)
}
public convenience init(extendedGraphemeClusterLiteral value: String) {
    self.init(stringLiteral: value)
}

Это инициализаторы «удобства», потому что они вызывают другой инициализатор, объявленный в классе.

Кроме того, инициализатор public init(stringLiteral value: String) не инициализирует все свойства. Подумайте о том, что происходит, если операторы if не выполняются. Вам нужно дать вашим свойствам (height, identifier и type) некоторые значения по умолчанию.

...