Мы можем переназначать для структур и классов операторы +, –, и т.д.
1 2 3 4 5 6 |
struct Vector2D { var x = 0.0, y = 0.0 } func + (left: Vector2D, right: Vector2D) -> Vector2D { return Vector2D(x: left.x + right.x, y: left.y + right.y) } |
Обратим внимание, что функция определена не внутри структуры, а определена как глобальная
Это позволит нам беспроблемно складывать векторы.
1 2 3 |
let vector = Vector2D(x: 3.0, y: 1.0) let anotherVector = Vector2D(x: 2.0, y: 4.0) let combinedVector = vector + anotherVector |
оператор + инфиксный и бинарный (должен находиться между двух операндов)
Так же можно переопределить унарные операторы, например ++ или —. Причем как префиксные -a, так и постфиксные a++. Достигается это за счет ключевых слов prefix/postfix
1 2 3 |
prefix func - (vector: Vector2D) -> Vector2D { return Vector2D(x: -vector.x, y: -vector.y) } |
Теперь мы можем получать вектор с обратными по знаку значениями x и y
1 2 3 |
let positive = Vector2D(x: 3.0, y: -4.0) let negative = -positive // (-3.0, 4.0) let alsoPositive = -negative // (3.0, -4.0) |
Compound Assignment Operators (составные опреаторы присваивания)
Это операторы присваивания в которых присоединен оператор (+, *, и т.д.)
1 2 3 4 5 6 7 |
func += (inout left: Vector2D, right: Vector2D) { left = left + right } var original = Vector2D(x: 1.0, y: 2.0) let vectorToAdd = Vector2D(x: 3.0, y: 4.0) original += vectorToAdd |
Можно комбинировать присваивание с префиксными и постфиксными модификаторами
1 2 3 4 5 6 7 8 |
prefix func ++ (inout vector: Vector2D) -> Vector2D { vector += Vector2D(x: 1.0, y: 1.0) return vector } var toIncrement = Vector2D(x: 3.0, y: 4.0) let afterIncrement = ++toIncrement // toIncrement = afterIncrement = (4.0, 5.0) |
Но нельзя переназначать как обычный оператор присваивания =, так и тернарный (a ? b : c)
Equivalence Operators (операторы равенства)
По умолчанию пользовательские классы и структуры не получают реализации равенства и неравенства (== и !=), так что их нужно так же определять как глобальные функции при необходимости
1 2 3 4 5 6 7 8 9 10 11 12 |
func == (left: Vector2D, right: Vector2D) -> Bool { return (left.x == right.x) && (left.y == right.y) } func != (left: Vector2D, right: Vector2D) -> Bool { return !(left == right) } let twoThree = Vector2D(x: 2.0, y: 3.0) let anotherTwoThree = Vector2D(x: 2.0, y: 3.0) if twoThree == anotherTwoThree { print("Векторы эквивалентны.") // будет напечатано } |