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

swi*_*ynx 6 types ios swift

我想有一个变量,它可以有多种类型(只有我定义的那些),如:

var example: String, Int = 0
example = "hi"
Run Code Online (Sandbox Code Playgroud)

此变量应该只能保存Int和String类型的值.

这可能吗?

谢谢你的帮助 ;)

Mar*_*n R 10

您正在寻找"具有相关值的枚举":

enum StringOrInt {
    case string(String)
    case int(Int)
}
Run Code Online (Sandbox Code Playgroud)

您可以指定字符串或整数:

var value: StringOrInt
value = .string("Hello")
// ...
value = .int(123)
Run Code Online (Sandbox Code Playgroud)

使用switch语句检索内容:

switch value {
case .string(let s): print("String:", s)
case .int(let n): print("Int:", n)
}
Run Code Online (Sandbox Code Playgroud)

如果声明符合Equatable协议,那么您还可以检查值是否相等:

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

let v = StringOrInt.string("Hi")
let w = StringOrInt.int(0)
if v == w { ... }
Run Code Online (Sandbox Code Playgroud)


few*_*ode 10

以下是如何实现它.完全符合您的期望.

protocol StringOrInt { }

extension Int: StringOrInt { }
extension String: StringOrInt { }

var a: StringOrInt = "10"
a = 10 //> 10
a = "q" //> "q"
a = 0.8 //> Error
Run Code Online (Sandbox Code Playgroud)

NB!我不建议你在生产代码中使用它.这可能会让你的队友感到困惑.

UPD:正如@Martin R所提到的:请注意,这仅限于"按惯例"限制可能的类型.任何模块(或源文件)都可以添加extension MyType: StringOrInt { }一致性.

  • 好话 谢谢!如果您不介意,我会将其添加到答案中。 (2认同)

Vya*_*lav 6

不,这对于类,结构等是不可能的。

但是协议是可能的。

您可以这样:

protocol Walker {
func go()
}
protocol Sleeper {
func sleep()
}

var ab = Walker & Sleeper
Run Code Online (Sandbox Code Playgroud)

甚至

    struct Person {
    var name: String
    }


var ab = Person & Walker & Sleeper
Run Code Online (Sandbox Code Playgroud)

但我不建议使用这种方式。

这更有用:

struct Person: Walker, Sleeper {
/// code
}
var ab = Person
Run Code Online (Sandbox Code Playgroud)

  • 这不会实现OP所要求的 - 协议上的“&”运算符创建一个具有*两个*协议要求的新协议,而不是表示结果类型可能只满足*一个*协议的要求(但始终至少有一个)。 (2认同)

Gle*_*enn 5

您可以使用Tuple.

例子:

let example: (String, Int) = ("hi", 0)
Run Code Online (Sandbox Code Playgroud)

并通过索引访问每个数据:

let stringFromExampleTuple = example.0 // "hi"
let intFromtExampleTuple = example.1 // 0
Run Code Online (Sandbox Code Playgroud)