var test: Int! {
didSet {
switch test {
case 1: print("one")
case 2: print("two")
default: print("something else")
}
}
}
var toupleTest: (one: Int, two: Int)! {
didSet {
switch toupleTest! {
case (1, 1): print("one, one")
case (2, 2): print("two, two")
default: print("something else")
}
}
}
test = 2 // prints "two"
toupleTest = (1, 1) // prints "one, one"
在 Int 值的情况下,一切都很好.
但是在元组的情况下,我必须解开两次可选包!否则我有一个编译错误.
看起来 swift 逻辑不一致。还是错误?
这是不一致的,但原因有点复杂。
为了使类型在switch
语句中使用,它需要符合Equatable
。
使用新的struct
类型查看此示例:
struct MyType: Equatable {
let x: Int
static func ==(lhs: MyType, rhs: MyType) -> Bool {
return lhs.x == rhs.x
}
}
var mytypeTest: MyType! {
didSet {
switch mytypeTest {
case MyType(x: 1): print("one")
case MyType(x: 2): print("two")
default: print("something else")
}
}
}
mytypeTest = MyType(x: 1)
这有效,但是如果您从MyType
中删除: Equatable
,则会出现错误运算符函数"~="要求"MyType"符合"等值"。
所以这是第一个提示。switch
使用~=
运算符进行比较,并且类型必须Equatable
。
那么如果我们尝试使用 '~=' 比较两个元组会发生什么:
if (1, 3) ~= (1, 3) {
print("same")
}
这给出了错误:类型"(Int,Int("不能符合"Eequalable";只有结构/枚举/类类型可以符合协议。
因此,这意味着元组不能在switch
中使用,我们知道这不是真的。
嗯,元组在switch
中有一个特殊的位置,它们用于模式匹配以解构元组。 例如:
let a = (1, 2)
switch a {
case let (x, y):
print("the tuple values are (x) and (y)")
}
这将打印the tuple values are 1 and 2
.
因此,元组在switch
中使用,用于使用模式匹配进行匹配和解构。 因此,您可以在switch
中使用元组,即使它不符合Equatable
,因为它具有这种特殊用途。
您的示例的问题在于模式与您正在打开的类型不匹配。 值的类型为(Int, Int)?
,模式为(Int, Int)
。
那么,如何在不强制解开元组值的情况下解决此问题? 通过向模式添加?
来更改模式以匹配:
var toupleTest: (one: Int, two: Int)! {
didSet {
switch toupleTest {
case (1, 1)?: print("one, one")
case (2, 2)?: print("two, two")
default: print("something else")
}
}
}
注意:添加?
也适用于您的Int
示例:
var test: Int! {
didSet {
switch test {
case 1?: print("one")
case 2?: print("two")
default: print("something else")
}
}
}
但这不是必需的,因为Int
是Equatable
的,而且 Swift 知道如何将Int?
与平等Int
进行比较。
我认为这是因为元组在 swift 中是值类型。默认类型也是默认类型。基本上,您的解包什么都不做,您只需标记此值将是非可选的。但是要访问其中的值,您必须解开可选的元组并到达值