我需要某种可以接受不需要创建大量样板代码的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
}
编辑:
为什么需要一个枚举
-使用枚举在XCode中自动完成
-使用switch
为什么必须为RawRepresentable
-通过RawValue
将其存储到持久性中。
-通过这样做,我也可以在ExpressibleByXXXXXXLiteral
下使用协议。
答案 0 :(得分:1)
需要是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
答案 1 :(得分:0)
这是我到目前为止提出的最好的解决方案。
我首先创建了一个枚举,其中包含两个带有关联值的案例,一个用于已知实体的子枚举,另一个用于未知实体。
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中提出的一件好事,所以我猜想会更少。