Перечисления Int со строковым представлением

Я хотел бы иметь перечисление Int, которое также можно «сериализовать» как Int или String.

enum Fruits : Int {
   case Banana = 1
   case Apple = 123
}

let favorite = Frutis(fromRaw: 1)
let banana = Fruits(from: "Banana")
assert(favorite==banana)
assert(favorite.rawValue == 1)
assert(String(describing: favorite) == "Banana")

Как я могу сделать это без реализации init(fromRaw:) и init(from:) для всех случаев? Перечисление содержит много записей, и я хотел бы избежать раздутого кода.

Связанный вопрос: Как упростить enum custom init (может быть даже дубликат). Также имейте в виду, что соглашение об именах Swift для случаев перечисления — lowerCamelCase.

Dávid Pásztor 04.04.2019 18:01
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
82
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете добавить его как вычисляемое свойство, например:

enum Fruits: Int {
    case banana = 1
    case apple = 123

    var stringRepresentation: String {
        return "\(self)"
    }
}

Таким образом, вы можете использовать его вот так let favorite = Fruits.banana.stringRepresentation, и если вы хотите получить значение Int, просто вызовите .rawValue.

Если вы хотите получить значение перечисления из строки, я думаю, вам придется использовать что-то вроде init(from: ).

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

Это работает всеми способами, кроме String -> Fruits. Кому я могу получить перечисление из строки?

Tamas 04.04.2019 18:09

Насколько мне известно, нет возможности сделать это динамически, и для этого потребуется выписать все возможные случаи.

bonky fronk 04.04.2019 18:20

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

enum Fruits : Int {
    case Banana = 1
    case Apple = 123

    var stringValue: String {
        return "\(self)"
    }

    init?(stringValue: String) {
        switch stringValue {
        case "Banana":
            self.init(rawValue: 1)
        case "Apple":
            self.init(rawValue: 123)
        default:
            self.init(rawValue: 0)
        }
    }
}

let favorite = Fruits(rawValue: 1)
let banana = Fruits(stringValue: "Banana")

assert(favorite==banana)
assert(favorite?.rawValue == 1)
assert(favorite?.stringValue == "Banana")
Ответ принят как подходящий

Я собрал это из связанных ответов, которые поддерживают все преобразования.

enum Fruits : Int, CaseIterable {
    case banana = 1
    case apple = 123

    init?<S: StringProtocol>(_ string: S) {
        guard let value = Fruits.allCases.first(where: { "\($0)" == string }) else {
            return nil
        }
        self = value
    }
    var stringRepresentation: String {
        return "\(self)"
    }
}

let favorite = Fruits(rawValue: 123)!
let apple = Fruits("apple")!
assert(favorite == apple)
assert(favorite.rawValue == 123)
assert(String(describing: favorite) == "apple")

Другие вопросы по теме