let p1 = (name: "John", age:12)
let p2 = (color: "Red", size:12)
if p1 == p2 {
print("equal")
}else {
print("not equal")
}
由于不同的参数名称和不编译的代码,我期望这两个元组不兼容。但它运作正常。很想知道如何。
Swift是否根据属性类型自动创建==
运算符,然后只需执行简单的lhs
与rhs
。是吗?
编辑:
func givePerson() -> (name: String, age: Int)? {
return ("alex", 2)
}
func extract() {
var p3 : (Name: String, age: Int)
if let person = giveName() as? (Name: String, age: Int) {
p3 = person
print(p3)
}else {
print("p3 not defined")
}
}
extract() // p3 not defined
我的extract
函数失败了,只是因为我得到了arity的名字不正确。这也是预期的吗?这与元组比较有何不同?
标准库defines tuple comparison operators用于2个元素元组,包括6个元素元组。它通过使用元编程工具GYB(Generate Your Boilerplate)来实现这一点,该工具允许嵌入式Python代码从模板生成文件。
生成的元组比较运算符最终看起来像:
public func == <A, B>(lhs: (A, B), rhs: (A, B)) -> Bool
public func == <A, B, C>(lhs: (A, B, C), rhs: (A, B, C)) -> Bool
public func == <A, B, C, D>(lhs: (A, B, C, D), rhs: (A, B, C, D)) -> Bool
// ...
所以用你的代码:
let p1 = (name: "John", age: 12)
let p2 = (color: "Red", size: 12)
if p1 == p2 {
print("equal")
} else {
print("not equal")
}
编译器将调用两元素元组比较运算符。您会注意到,定义的元组比较运算符都没有为其参数使用元组标签。两者兼备的原因
(name: String, age: Int)
和(color: String, size: Int)
可以传递给(A, B)
,因为编译器实现了一个可以去除其标签元组的隐式转换。所以这两个参数都剥离了它们的标签,并且都作为(String, Int)
传递。
这就是使以下合法的原因:
let p1 = (name: "John", age: 12)
let p2: (String, Int) = p1 // Legal.
事情变得更加奇怪,编译器还有一个隐式转换,可以向元组添加任意标签:
let p1 = ("John", 12)
let p2: (foo: String, bar: Int) = p1 // Legal.
但是禁止直接重命名标签:
// Indirect renaming ✅
let p1 = (name: "John", age: 12)
let p2: (String, Int) = p1
let p3: (foo: String, bar: Int) = p2
// Put together ✅
let p4: (foo: String, bar: Int) = p1 as (String, Int)
// Direct renaming ❌
let p4 = (name: "John", age: 12)
let p5: (foo: String, bar: Int) = p4
这就是你用as?
演员所看到的行为。与上面的示例一样,首先强制转换为未标记的表单:
func givePerson() -> (name: String, age: Int)? {
return ("alex", 2)
}
func extract() {
var p3: (Name: String, age: Int)
if let person = givePerson() as (String, Int)? as? (Name: String, age: Int) {
p3 = person
print(p3)
} else {
print("p3 not defined")
}
}
extract() // (Name: "alex", age: 2)
元组有==
运算符定义(对于2到7的元组),但由于元组不符合协议,它们不是Equatable
。
标准库只定义了6个独立的qazxsw poi运算符,每个运算符采用两个元组的arity 2,3,...,7。