【发布时间】:2019-03-30 23:19:45
【问题描述】:
我想要一个变量,它可以有多种类型(我定义的只有一种),比如:
var example: String, Int = 0
example = "hi"
这个变量应该只能保存 Int 和 String 类型的值。
这可能吗?
感谢您的帮助;)
【问题讨论】:
-
不,不可能
我想要一个变量,它可以有多种类型(我定义的只有一种),比如:
var example: String, Int = 0
example = "hi"
这个变量应该只能保存 Int 和 String 类型的值。
这可能吗?
感谢您的帮助;)
【问题讨论】:
“具有关联值的枚举”可能是您正在寻找的:
enum StringOrInt {
case string(String)
case int(Int)
}
您可以分配字符串或整数:
var value: StringOrInt
value = .string("Hello")
// ...
value = .int(123)
检索内容是通过 switch 语句完成的:
switch value {
case .string(let s): print("String:", s)
case .int(let n): print("Int:", n)
}
如果您声明符合Equatable 协议,那么
您还可以检查值是否相等:
enum StringOrInt: Equatable {
case string(String)
case int(Int)
}
let v = StringOrInt.string("Hi")
let w = StringOrInt.int(0)
if v == w { ... }
【讨论】:
enum Transformer<T: Equatable, U: Equatable> { case first(T); case second(U) }
Result 类型(保存成功值或错误)。
enum StringOrInt: Equatable 中添加了“Equatable”一致性?
protocol StringOrInt { }
extension Int: StringOrInt { }
extension String: StringOrInt { }
var a: StringOrInt = "10"
a = 10 //> 10
a = "q" //> "q"
a = 0.8 //> Error
注意!我不建议您在生产代码中使用它。这可能会让你的队友感到困惑。
UPD: 正如@Martin R 提到的:请注意,这仅“按照惯例”限制了可能的类型。任何模块(或源文件)都可以添加extension MyType: StringOrInt { } 一致性。
【讨论】:
extension MyType: StringOrInt { } 一致性。
ArrayOrOptional 这样的类型,因为 Optional 是一个协议。
不,这对于类、结构等是不可能的。
但是协议是可能的。
你可以这样做:
protocol Walker {
func go()
}
protocol Sleeper {
func sleep()
}
var ab = Walker & Sleeper
甚至
struct Person {
var name: String
}
var ab = Person & Walker & Sleeper
但我不推荐使用这种方式。
这个更有用:
struct Person: Walker, Sleeper {
/// code
}
var ab = Person
【讨论】:
& 运算符创建一个具有 both 协议要求的新协议,而不是表达结果类型可能只满足一个协议的要求(但总是至少一个)。
您可以使用Tuple。
例子:
let example: (String, Int) = ("hi", 0)
并通过索引访问每个数据:
let stringFromExampleTuple = example.0 // "hi"
let intFromtExampleTuple = example.1 // 0
【讨论】: