Have a variable with multiple types in Swift

后端 未结 4 885
北海茫月
北海茫月 2021-01-12 03:24

I would like to have a variable, which can have multiple types (only ones, I defined), like:

var example: String, Int = 0
example = \"hi\"

相关标签:
4条回答
  • 2021-01-12 03:44

    Here is how you can achieve it. Works exactly how you'd expect.

    protocol StringOrInt { }
    
    extension Int: StringOrInt { }
    extension String: StringOrInt { }
    
    var a: StringOrInt = "10"
    a = 10 //> 10
    a = "q" //> "q"
    a = 0.8 //> Error
    

    NB! I would not suggest you to use it in production code. It might be confusing for your teammates.

    UPD: as @Martin R mentioned: Note that this restricts the possible types only “by convention.” Any module (or source file) can add a extension MyType: StringOrInt { } conformance.

    0 讨论(0)
  • 2021-01-12 03:45

    An “enumeration with associated value” might be what you are looking for:

    enum StringOrInt {
        case string(String)
        case int(Int)
    }
    

    You can either assign a string or an integer:

    var value: StringOrInt
    value = .string("Hello")
    // ...
    value = .int(123)
    

    Retrieving the contents is done with a switch-statement:

    switch value {
    case .string(let s): print("String:", s)
    case .int(let n): print("Int:", n)
    }
    

    If you declare conformance to the Equatable protocol then you can also check values for equality:

    enum StringOrInt: Equatable {
        case string(String)
        case int(Int)
    }
    
    let v = StringOrInt.string("Hi")
    let w = StringOrInt.int(0)
    if v == w { ... }
    
    0 讨论(0)
  • 2021-01-12 03:46

    No, this is not possible for classes, structs, etc.

    But it is possible for protocols.

    You can this:

    protocol Walker {
    func go()
    }
    protocol Sleeper {
    func sleep()
    }
    
    var ab = Walker & Sleeper
    

    or even

        struct Person {
        var name: String
        }
    
    
    var ab = Person & Walker & Sleeper
    

    But I don't recomment use this way.

    More useful this:

    struct Person: Walker, Sleeper {
    /// code
    }
    var ab = Person
    
    0 讨论(0)
  • 2021-01-12 03:49

    You can use Tuple.

    Example:

    let example: (String, Int) = ("hi", 0)
    

    And access each data by index:

    let stringFromExampleTuple = example.0 // "hi"
    let intFromtExampleTuple = example.1 // 0
    
    0 讨论(0)
提交回复
热议问题