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

标签 swift enums

我需要某种可以接受任何 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)值(value)。

这可以通过使用 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 下的协议(protocol)。

最佳答案

需要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

关于swift - 是否有一个快速数据结构可以包含一个可以是任何类型并且可以切换的rawValue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52289307/

相关文章:

ios - 无法从 Swift 继承 NSInputStream(initWithData : unrecognizer selector)

ios - 追加到 NSString 方法的开头

ios - "Binary operator ' ~= ' cannot be applied to operands of type '

c++ - 我们可以在函数中定义枚举吗?

swift - 使用 Core Data 属性创建 UI 本地通知

swift - TableView 在新 Controller 上显示不同的图像

ios - 如果已经选择了 UITableViewCell,不要继续执行?

enums - 以分类变量(枚举)作为输入的神经网络

c++ - 使用 Qt 枚举转换为 qint32

java - 使用枚举变量切换字符串