Есть ли быстрая структура данных, которая может содержать rawValue, который может быть любого его типа и может быть переключаемым - PullRequest
0 голосов
/ 12 сентября 2018

Мне нужен какой-то тип enum, который может принимать любые StringLiteralType, в которых мне не нужно создавать много шаблонного кода.

Вот пример кода, который у меня есть.

enum Sample: RawRepresentable {
    case foo
    case bar
    case unknown(String)

    init?(rawValue: String) {
        if let correspondingValue = Key(rawValue: rawValue)?.correspondingValue {
            self = correspondingValue
        } else {
            self = .unknown(rawValue)
        }
    }

    private enum Key: String {
        case foo
        case bar

        var correspondingValue: Sample {
            switch self {
            case .foo: return .foo
            case .bar: return .bar
            }
        }

        init?(withSample sample: Sample) {
            switch sample {
            case .foo: self = .foo
            case .bar: self = .bar
            case .unknown: return nil
            }
        }
    }

    var rawValue: String {
        switch self {
        case let .unknown(value): return value
        default: return Key(withSample: self)?.rawValue ?? ""
        }
    }
}

Я хочу иметь определенные случаи (foo, bar и т. Д.), В которых есть значения по умолчанию, которые я могу использовать для переключения, а затем я хочу получить unkown(String), который может содержать любое значение.

Это можно легко сделать, просто используя String и какой-нибудь Constants, например, подобный этому.

enum Constants {
    static let foo = "foo"
    static let bar = "bar"
}

// sample usage

let someString = "aaaa"

let sample = Sample(rawValue: someString)! // don't mind the implicit unwrapping
switch sample {
case Constants.foo:
    // do something
case Constants.bar:
    // do something
default:
    // do something with unknown someString
}

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

let someString = "aaaa"

let sample = Sample(rawValue: someString)! // don't mind the implicit unwrapping
switch sample {
case .foo:
    // do something
case .bar:
    // do something
case .unknown(let value):
    // do something
}

РЕДАКТИРОВАТЬ:

Почему это должно быть Enum - Автозаполнение в XCode с использованием перечислений - Добавление функциональности будет легко при добавлении новых случаев при использовании switch

Почему это должно быть RawRepresentable - Это сохраняется для сохранения через RawValue.- Я также могу использовать протоколы под ExpressibleByXXXXXXLiteral, делая это.

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Это лучшее решение, которое я сделал до сих пор.

Сначала я создал перечисление, которое содержит два случая со связанными значениями, одно для подгруппы известных сущностей, а другое для неизвестных сущностей.

enum Foo {
    case known(Bar)
    case unknown(String)

    enum Bar: String {
        case fiz, baz
    }
}

Затем я расширил сказанноеenum, чтобы иметь RawRepresentable возможностей

extension Foo: RawRepresentable {
    init?(rawValue: String) {
        if let bar = Bar(rawValue: rawValue) {
            self = .known(bar)
        } else {
            self = .unknown(rawValue)
        }
    }

    init(stringValue: String) {
        self.init(rawValue: stringValue)!
    }

    var rawValue: String {
        switch self {
        case let .known(bar): return bar.rawValue
        case let .unknown(string): return string
        }
    }
}

Вот пример использования.

let foo: Foo = .known(.fiz)

switch foo {
case .known(.fiz):
    ... do something
case .known(.baz):
    ... do something
case .unknown(let str):
    ... do something
}

PS: Возможно, это было бы неплохо предложить в Swift Evolution, так что было бы меньшеОбразец, я думаю.

0 голосов
/ 12 сентября 2018

Нужно ли , чтобы быть RawRepresentable?Код ниже работает в соответствии с вашими требованиями ...

enum Sample {
    case foo, bar, unknown(StringLiteralType)

    init(_ string: StringLiteralType) {
        switch string {
        case "foo": self = .foo
        case "bar": self = .bar
        default: self = .unknown(string)
        }
    }
}


let sample = Sample("aaa")
switch sample {
case .foo:
    print("foo")
case .bar:
    print("bar")
case .unknown(let value):
    print(value)
}
// aaa

Редактировать

enum Sample: RawRepresentable {
    case foo, bar, unknown(StringLiteralType)
    enum Keys: String {
        case foo, bar
        var sample: Sample {
            switch self {
            case .foo: return .foo
            case .bar: return .bar
            }
        }
    }

    init(rawValue: StringLiteralType) {
        self = Keys(rawValue: rawValue)?.sample ?? .unknown(rawValue)
    }

    var rawValue: String {
        switch self {
        case .foo: return Keys.foo.rawValue
        case .bar: return Keys.bar.rawValue
        case .unknown(let value): return value
        }
    }
}

print(Sample(rawValue: "aaa").rawValue) // aaa
print(Sample(rawValue: "foo").rawValue) // foo
print(Sample.foo.rawValue) // foo
print(Sample.bar.rawValue) // bar
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...