代码之家  ›  专栏  ›  技术社区  ›  Zonily Jame

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

  •  2
  • Zonily Jame  · 技术社区  · 6 年前

    我需要一个能接受任何 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 ?? ""
            }
        }
    }
    

    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 通过这样做。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Ashley Mills    6 年前

    是吗 需要 成为 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
    
        2
  •  0
  •   Zonily Jame    6 年前

    我首先创建了一个枚举,其中包含两个具有关联值的case,一个用于已知实体的子枚举,另一个用于未知实体。

    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
    }
    

    附言:这可能是一个很好的建议,在快速发展,所以会有较少的样板我猜。