Суб перечисление rawValue - PullRequest
1 голос
/ 16 июня 2019

Рассмотрим следующий код, где я объявил enum с вложенными перечислениями внутри него.

enum LocalizeKey {
case message(Messages)
case buttons(Buttons)
enum Buttons: String {
    case remove = "Remove"
    case add = "Add"
}
enum Messages: String {
    case success = "Success"
    case failure = "Failure"
 }
}

В обычном enum без вложенных перечислений мы можем легко получить доступ к свойству .rawValue и получить необработанное значение любого выбранного случая.

В этом случае я создал такую ​​функцию, чтобы проверить, что я получаю.

func keyString(for type: LocalizeKey) {
    print(type)
 }
keyString(for: .message(.failure)) // usage

Проблема : для этого перечисления LocalizeKey нет других свойств, кроме .self.

Чего я пытаюсь достичь: возможно, вы можете связать по именам, я пытаюсь обернуть свои локализованные ключи, чтобы я мог легко получить к ним доступ в зависимости от типа ключа и т. Д., И rawValue то, что относится к фактической клавише, перейдет в функцию getLocalizedValue.

Выход на игровую площадку : при использовании функции над выходом игровая площадка была

сообщение (__ lldb_expr_21.LocalizeKey.Messages.failure)

Редактировать: без необходимости создания переменной, которая переключает себя в каждом случае, представьте, если бы у нас был ключ +400, который, вероятно, был бы огромным беспорядком.

Ответы [ 3 ]

1 голос
/ 16 июня 2019

Вы должны будете где-то переключиться. Если есть только несколько «под-перечислений», вероятно, проще всего просто написать переключатель вручную:

func keyString(for type: LocalizeKey) {
  switch type {
  case .message(let message):
    print(message.rawValue)
  case .buttons(let button):
    print(button.rawValue)
  }
}

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

1 голос
/ 17 июня 2019

Хотя упомянутые ответы дают решение, я бы упомянул проблему самого подхода:

На этом этапе каждый новый регистр (ключ) должен быть добавлен в ваш оператор switch с соответствующим значением, которое представляется нежелательным стандартным кодированием; Я предполагаю, что вы могли бы представить, как это будет выглядеть при наличии многих дел в перечислениях.

Поэтому я бы рекомендовал придерживаться более динамичного подхода вместо добавления значения каждого случая вручную в операторе switch. Пример:

protocol Localizable {
    var value: String { get }
}

extension RawRepresentable where Self: Localizable, Self.RawValue == String {
    var value: String { return rawValue }
}

extension CustomStringConvertible where Self: RawRepresentable, Self.RawValue == String {
    var description: String { return rawValue }
}

struct LocalizeKey {

    enum Buttons: String, Localizable, CustomStringConvertible {
        case remove = "Remove"
        case add = "Add"
    }

    enum Messages: String, Localizable, CustomStringConvertible {
        case success = "Success"
        case failure = "Failure"
    }
}

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

Исходя из этого, вы все еще можете реализовать свою функцию как:

func keyString(for type: Localizable) {
    print(type)
}

Использование:

keyString(for: LocalizeKey.Buttons.add) // Add
keyString(for: LocalizeKey.Messages.success) // Success

ИМО, я считаю, что называть это так кажется более читабельным, простым, чем предлагаемый подход (keyString(for: .message(.failure))).

1 голос
/ 16 июня 2019

Вам нужно switch для параметра type и выполнить сопоставление с шаблоном:

switch type {
    case .message(let messages): return messages.rawValue
    case .buttons(let buttons): return buttons.rawValue
}

Вы также можете сделать это расширение LocalizeKey:

extension LocalizeKey {
    var keyString: String {
        switch self {
            case .message(let messages): return messages.rawValue
            case .buttons(let buttons): return buttons.rawValue
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...