Стандартная библиотека определяет операторы сравнения кортежей для кортежей из 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)