是否有一个swift数据结构可以包含一个rawValue,该rawValue可以是它的任何类型,并且可以切换

是否有一个swift数据结构可以包含一个rawValue,该rawValue可以是它的任何类型,并且可以切换,swift,enums,Swift,Enums,我需要某种枚举,它可以接受任何StringLiteralType,我不需要在其中创建大量样板代码 下面是我的样板代码示例 enum Sample: RawRepresentable { case foo case bar case unknown(String) init?(rawValue: String) { if let correspondingValue = Key(rawValue: rawValue)?.correspondingV

我需要某种枚举,它可以接受任何
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等),这些案例有我可以用来切换的默认值,然后我想要一个
unknown(String)
,它可以包含任何值

例如,只需使用
字符串
和某种类型的
常量
,就可以很容易地做到这一点

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
}
编辑:

为什么它需要是枚举 -使用枚举在XCode中自动完成 -使用
开关添加新案例时,添加功能将很容易

为什么它需要具有代表性 -它通过
RawValue
存储到持久性中。 -通过这样做,我还可以使用
expressiblebyxxxxxliteral
下的协议。

它是否需要是
raw可表示的
?下面的代码符合您的要求

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 Foo {
    case known(Bar)
    case unknown(String)

    enum Bar: String {
        case fiz, baz
    }
}
然后,我扩展了上述枚举,使其具有
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中,这可能是一个很好的建议,因此我想会有更少的样板文件。

它需要是可表示的,因为它使用stringValue存储在某个地方。我会更新问题的其他要求和原因。我明白你的问题。我编辑了我的答案,但后来意识到我提出的代码与你原来的问题几乎相同
let foo: Foo = .known(.fiz)

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