简体   繁体   English

在Swift中有一个具有多种类型的变量

[英]Have a variable with multiple types in Swift

I would like to have a variable, which can have multiple types (only ones, I defined), like: 我想有一个变量,它可以有多种类型(只有我定义的那些),如:

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

This variable should be able to hold only values of type Int and String. 此变量应该只能包含Int和String类型的值。

Is this possible? 这可能吗?

Thanks for your help ;) 谢谢你的帮助 ;)

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! 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. UPD:正如@Martin R所提到的:请注意,这仅限于“按惯例”限制可能的类型。任何模块(或源文件)都可以添加extension MyType: StringOrInt { }一致性。

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语句检索内容:

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: 如果声明符合Equatable协议,那么您还可以检查值是否相等:

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

let v = StringOrInt.string("Hi")
let w = StringOrInt.int(0)
if v == w { ... }

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

You can use Tuple . 你可以使用Tuple

Example: 例:

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

And access each data by index: 并通过索引访问每个数据:

let stringFromExampleTuple = example.0 // "hi"
let intFromtExampleTuple = example.1 // 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM