是否有一个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
}