Swift предоставляет несколько расширенных операторов, которые выполняют более сложные манипуляции со значениями. К ним относятся все побитовые и битовые операторы, с которыми вы будете знакомы из C и Objective-C.
В отличие от арифметических операторов в C, арифметические операторы в Swift по умолчанию не переполняются. Поведение переполнения ловится и сообщается как ошибка. Чтобы включить режим переполнения, используйте второй набор арифметических операторов Swift, которые по умолчанию переполняются, например, оператор сложения переполнения ( &+
). Все эти операторы переполнения начинаются с амперсанда ( &
).
Когда вы определяете свои собственные структуры, классы и перечисления, может быть полезно предоставить свои собственные реализации стандартных операторов Swift для этих пользовательских типов. Swift упрощает предоставление специализированных реализаций этих операторов и точно определяет их поведение для каждого создаваемого вами типа.
Вы не ограничены предопределенными операторами. Swift дает вам свободу определять свои собственные операторы инфикса, префикса, постфикса и присваивания с пользовательскими значениями приоритета и ассоциативности. Эти операторы могут использоваться и приниматься в вашем коде, как любые из предопределенных операторов, и вы даже можете расширять существующие типы для поддержки определенных вами пользовательских операторов.
Битовые операторы
Битовые операторы позволяют вам управлять отдельными битами необработанных данных в структуре данных. Они часто используются в низкоуровневом программировании, таком как графическое программирование и создание драйверов устройств. Побитовые операторы также могут быть полезны при работе с необработанными данными из внешних источников, такими как данные кодирования и декодирования, для связи по пользовательскому протоколу.
Swift поддерживает все побитовые операторы, найденные в C, как описано ниже.
Побитовый оператор НЕ
Побитовое НЕ оператор ( ~
) инвертирует все биты в ряду:
Побитовый оператор NOT является префиксным оператором и появляется непосредственно перед значением, с которым он работает, без пробелов:
let initialBits: UInt8 = 0b00001111
let invertedBits = ~initialBits // equals 11110000
UInt8
целые числа имеют восемь битов и могут хранить любое значение между 0
и 255
. В этом примере UInt8
целое число инициализируется двоичным значением 00001111
, для которого первые четыре бита установлены 0
, а вторые четыре бита установлены 1
. Это эквивалентно десятичному значению 15
.
Затем побитовый оператор НЕ используется для создания новой константы с именем invertedBits
, которая равна initialBits
, но со всеми инвертированными битами. Нули становятся единицами, а единицы становятся нулями. Значение invertedBits
is 11110000
, которое равно десятичному значению без знака 240
.
Побитовое И Оператор
Побитовое И оператор ( &
) объединяет биты двух чисел. Он возвращает новый номер, биты которого установлены 1
только в том случае, если биты равны 1
в обоихвходных числах:
В приведенном ниже примере значения firstSixBits
и lastSixBits
оба имеют четыре средних бита, равных 1
. Побитовый оператор И объединяет их, чтобы получить число 00111100
, равное десятичному значению без знака 60
:
let firstSixBits: UInt8 = 0b11111100
let lastSixBits: UInt8 = 0b00111111
let middleFourBits = firstSixBits & lastSixBits // equals 00111100
Побитовый оператор ИЛИ
Оператор побитового ИЛИ ( |
) сравнивает биты двух чисел. Оператор возвращает новый номер, биты которого установлены, 1
если биты равны 1
в любом входном номере:
В приведенном ниже примере значения someBits
и moreBits
имеют разные биты, установленные на 1
. Оператор побитового ИЛИ объединяет их в число 11111110
, равное десятичному числу без знака 254
:
let someBits: UInt8 = 0b10110010
let moreBits: UInt8 = 0b01011110
let combinedbits = someBits | moreBits // equals 11111110
Побитовый оператор XOR
Оператор побитовое исключающее или «исключающее ИЛИ оператора» ( ^
), сравнивает биты двух чисел. Оператор возвращает новый номер, биты которого установлены на то, 1
где входные биты различны, и установлены на то, 0
где входные биты одинаковы:
В приведенном ниже примере значения firstBits
и для otherBits
каждого из них установлены биты 1
в местоположении, которого нет у другого. Побитовый оператор XOR устанавливает оба этих бита 1
в свое выходное значение. Все остальные биты firstBits
и otherBits
совпадают, и устанавливаются 0
в выходное значение:
let firstBits: UInt8 = 0b00010100
let otherBits: UInt8 = 0b00000101
let outputBits = firstBits ^ otherBits // equals 00010001
Побитовые операторы левого и правого сдвига
Оператор побитового сдвига влево ( <<
) и оператор побитового сдвига вправо ( >>
) перемещают все биты числа влево или вправо на определенное количество мест в соответствии с правилами, определенными ниже.
Побитовые сдвиги влево и вправо приводят к умножению или делению целого числа на коэффициент два. Сдвиг целочисленных битов влево на одну позицию удваивает его значение, тогда как сдвиг его вправо на одну позицию вдвое уменьшает его значение.
Поведение смещения для целых чисел без знака
Поведение сдвига битов для целых чисел без знака выглядит следующим образом:
- Существующие биты перемещаются влево или вправо на требуемое количество мест.
- Любые биты, которые перемещаются за пределы целочисленной памяти, отбрасываются.
- Нули вставляются в пустые места после того, как исходные биты перемещаются влево или вправо.
Этот подход известен как логический сдвиг .
На рисунке ниже показаны результаты ( смещенные влево по месту) и ( смещенные вправо по месту). Синие числа сдвинуты, серые числа отброшены, и оранжевые нули вставлены:11111111 << 1
11111111
1
11111111 >> 1
11111111
1
Вот как выглядит сдвиг битов в коде Swift:
let shiftBits: UInt8 = 4 // 00000100 in binary
shiftBits << 1 // 00001000
shiftBits << 2 // 00010000
shiftBits << 5 // 10000000
shiftBits << 6 // 00000000
shiftBits >> 2 // 00000001
Вы можете использовать сдвиг битов для кодирования и декодирования значений в других типах данных:
let pink: UInt32 = 0xCC6699
let redComponent = (pink & 0xFF0000) >> 16 // redComponent is 0xCC, or 204
let greenComponent = (pink & 0x00FF00) >> 8 // greenComponent is 0x66, or 102
let blueComponent = pink & 0x0000FF // blueComponent is 0x99, or 153
В этом примере используется UInt32
константа, вызываемая pink
для хранения значения цвета каскадных таблиц стилей для розового цвета. Значение цвета CSS #CC6699
записывается 0xCC6699
в виде шестнадцатеричного числа в Swift. Затем этот цвет разлагается на его компоненты red ( CC
), green ( 66
) и blue ( 99
) с помощью оператора побитового оператора AND ( &
) и оператора побитового сдвига вправо ( >>
).
Красный компонент получается путем выполнения побитового И между числами 0xCC6699
и 0xFF0000
. Нули в 0xFF0000
действительности «маскируют» второй и третий байты 0xCC6699
, вызывая 6699
их игнорирование и оставляя 0xCC0000
в результате.
Затем это число сдвигается на 16 позиций вправо ( ). Каждая пара символов в шестнадцатеричном числе использует 8 битов, поэтому перемещение на 16 позиций вправо преобразуется в . Это так же, как , который имеет десятичное значение .>> 16
0xCC0000
0x0000CC
0xCC
204
Аналогично, зеленый компонент получается путем выполнения побитового И между числами 0xCC6699
и 0x00FF00
, что дает выходное значение 0x006600
. Это выходное значение затем смещается на восемь позиций вправо, давая значение 0x66
, которое имеет десятичное значение 102
.
Наконец, синий компонент получается путем выполнения побитового И между числами 0xCC6699
и 0x0000FF
, что дает выходное значение 0x000099
. Нет необходимости сдвигать это вправо, так как 0x000099
уже равно 0x99
, что имеет десятичное значение 153
.
Изменение поведения для подписанных целых чисел
Поведение сдвига является более сложным для целых чисел со знаком, чем для целых чисел без знака, потому что целые числа со знаком представлены в двоичном виде. (Приведенные ниже примеры для простоты основаны на 8-разрядных знаковых целых числах, но те же принципы применимы к целым числам со знаком любого размера.)
Целые числа со знаком используют свой первый бит (известный как знаковый бит ), чтобы указать, является ли целое число положительным или отрицательным. Знаковый бит 0
означает положительный, а знаковый бит 1
означает отрицательный.
Остальные биты (известные как биты значения ) хранят фактическое значение. Положительные числа хранятся точно так же, как и для целых чисел без знака, считая от 0
.
Знаковый бит 0
(означает «положительный»), а семь битов значения - это просто число 4
, записанное в двоичной записи.
Отрицательные числа, однако, хранятся по-разному. Они сохраняются путем вычитания их абсолютного значения из 2
степени n
, где n
число битов значения. Восьмибитное число имеет семь битов значения, так что это означает 2
степень 7
или 128
.
На этот раз знаковый бит 1
(означает «отрицательный»), а семь битов значения имеют двоичное значение 124
(которое ):128 - 4
Эта кодировка для отрицательных чисел называется представлением дополнения до двух . Это может показаться необычным способом представления отрицательных чисел, но у него есть несколько преимуществ.
Во- первых, вы можете добавить -1
к -4
, просто выполняя стандартный двоичный добавление всех восьми битов (включая знаковый бит), и отбрасывая все , что не укладывается в восемь бит.
Во-вторых, представление дополнения двух также позволяет вам сдвигать биты отрицательных чисел влево и вправо, как положительные числа, и при этом все равно удваивать их за каждый сдвиг влево или делить пополам их за каждый сдвиг вправо , Для достижения этого используется дополнительное правило, когда целые числа со знаком сдвигаются вправо: когда вы сдвигаете целые числа со знаком вправо, применяйте те же правила, что и для целых чисел без знака, но заполняйте все пустые биты слева битом знака , а чем с нуля.
Это действие гарантирует, что целые числа со знаком будут иметь одинаковый знак после их смещения вправо, и называется арифметическим сдвигом .
Из-за особого способа хранения положительных и отрицательных чисел сдвиг любого из них вправо перемещает их ближе к нулю. Сохранение бита знака в течение этого сдвига означает, что отрицательные целые числа остаются отрицательными, поскольку их значение приближается к нулю.
Операторы переполнения
Если вы попытаетесь вставить число в целочисленную константу или переменную, которая не может содержать это значение, по умолчанию Swift сообщает об ошибке, а не позволяет создать недопустимое значение. Такое поведение обеспечивает дополнительную безопасность при работе с слишком большими или слишком маленькими числами.
Например, Int16
целочисленный тип может содержать любое целое число со знаком между -32768
и 32767
. Попытка установить Int16
константу или переменную в число вне этого диапазона вызывает ошибку:
var potentialOverflow = Int16.max
// potentialOverflow equals 32767, which is the maximum value an Int16 can hold
potentialOverflow += 1
// this causes an error
Обеспечение обработки ошибок, когда значения становятся слишком большими или слишком маленькими, дает вам гораздо большую гибкость при кодировании для граничных условий.
Однако, если вы хотите, чтобы условие переполнения урезало количество доступных битов, вы можете включить это поведение, а не вызывать ошибку. Swift предоставляет три арифметических оператора переполнения, которые выбирают поведение переполнения для целочисленных вычислений. Все эти операторы начинаются с амперсанда ( &
):
- Добавление переполнения (
&+
) - Вычитание переполнения (
&-
) - Переполнение умножения (
&*
)
Переполнение значения
Числа могут переполняться как в положительном, так и в отрицательном направлении.
Вот пример того, что происходит, когда целое число без знака может переполняться в положительном направлении, используя оператор сложения переполнения ( &+
):
var unsignedOverflow = UInt8.max
// unsignedOverflow equals 255, which is the maximum value a UInt8 can hold
unsignedOverflow = unsignedOverflow &+ 1
// unsignedOverflow is now equal to 0
Переменная unsignedOverflow
инициализируется с максимальным значением, которое UInt8
может содержать ( 255
или 11111111
в двоичном виде). Затем он увеличивается с 1
помощью оператора сложения переполнения ( &+
). Это увеличивает его двоичное представление только на размер, который UInt8
может содержать a , вызывая его переполнение за его пределы, как показано на диаграмме ниже. Значение, которое остается в границах UInt8
после добавления переполнения 00000000
, равно нулю.
Нечто подобное происходит, когда целое число без знака может переполниться в отрицательном направлении. Вот пример использования оператора вычитания переполнения ( &-
):
var unsignedOverflow = UInt8.min
// unsignedOverflow equals 0, which is the minimum value a UInt8 can hold
unsignedOverflow = unsignedOverflow &- 1
// unsignedOverflow is now equal to 255
Минимальное значение, которое UInt8
может содержать a, равно нулю или 00000000
в двоичном виде. Если вы вычли 1
из 00000000
использования оператора вычитания переполнения ( &-
), число будет переполнено и будет округлено до 11111111
или 255
в десятичном виде.
Переполнение также происходит для целых чисел со знаком. Все сложение и вычитание для целых чисел со знаком выполняется поразрядным образом, причем знаковый бит включается как часть чисел, которые добавляются или вычитаются.
var signedOverflow = Int8.min
// signedOverflow equals -128, which is the minimum value an Int8 can hold
signedOverflow = signedOverflow &- 1
// signedOverflow is now equal to 127
Минимальное значение, которое Int8
может содержать -128
, или 10000000
в двоичном виде. Вычитание 1
из этого двоичного числа с помощью оператора переполнения дает двоичное значение 01111111
, которое переключает бит знака и дает положительное 127
максимальное положительное значение, которое Int8
может содержать.
Как для целых чисел со знаком, так и для без знака переполнение в положительном направлении оборачивается от максимального действительного целочисленного значения обратно к минимуму, а переполнение в отрицательном направлении - от минимального значения до максимального.
Приоритетность и ассоциативность
Приоритет оператора дает некоторым операторам более высокий приоритет, чем другим; эти операторы применяются в первую очередь.
Ассоциативность операторов определяет, как операторы с одинаковым приоритетом группируются вместе - либо слева, либо справа. Думайте об этом как о значении «они ассоциируются с выражением слева от них» или «они ассоциируются с выражением справа».
При определении порядка вычисления составного выражения важно учитывать приоритет каждого оператора и его ассоциативность. Например, приоритет оператора объясняет, почему следующее выражение равно 17
.
2 + 3 % 4 * 5
// this equals 17
Если вы читаете строго слева направо, вы можете ожидать, что выражение будет вычислено следующим образом:
2
плюс3
равно5
5
остаток4
равен1
1
времена5
равны5
Однако фактический ответ - 17
нет 5
. Операторы с более высоким приоритетом оцениваются перед операторами с более низким приоритетом. В Swift, как и в C, оператор остатка ( %
) и оператор умножения ( *
) имеют более высокий приоритет, чем оператор сложения ( +
). В результате они оба оцениваются до того, как добавление будет рассмотрено.
Однако остаток и умножение имеют тот же приоритет, что и другие. Чтобы определить точный порядок использования, вам также необходимо учесть их ассоциативность. Остаток и умножение ассоциируются с выражением слева. Думайте об этом как о добавлении неявных скобок вокруг этих частей выражения, начиная с их левой стороны:
2 + ((3 % 4) * 5)
(3 % 4)
есть 3
, так что это эквивалентно:
2 + (3 * 5)
(3 * 5)
есть 15
, так что это эквивалентно:
2 + 15
Этот расчет дает окончательный ответ 17
.
Для получения информации об операторах, предоставляемых стандартной библиотекой Swift, включая полный список групп приоритетов операторов и параметров ассоциативности .
ЗАМЕТКА
Приоритеты операторов Свифта и правила ассоциативности проще и более предсказуемы, чем в C и Objective-C. Однако это означает, что они не совсем такие же, как в языках на основе Си. Будьте осторожны, чтобы убедиться, что взаимодействие с оператором по-прежнему ведет себя так, как вы собираетесь при переносе существующего кода в Swift.
Операторские методы
Классы и структуры могут предоставлять свои собственные реализации существующих операторов. Это известно как перегрузка существующих операторов.
В приведенном ниже примере показано, как реализовать оператор арифметического сложения ( +
) для пользовательской структуры. Оператор арифметического сложения является бинарным оператором, потому что он работает с двумя целями и называется инфиксным, потому что он появляется между этими двумя целями.
В этом примере определяется Vector2D
структура для двумерного вектора положения , за которым следует определение метода оператора для сложения экземпляров структуры:(x, y)
Vector2D
struct Vector2D {
var x = 0.0, y = 0.0
}
extension Vector2D {
static func + (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
}
Метод оператора определяется как метод типа Vector2D
с именем метода, совпадающим с оператором, который должен быть перегружен ( +
). Поскольку сложение не является частью существенного поведения для вектора, метод типа определяется в расширении, Vector2D
а не в объявлении основной структуры Vector2D
. Поскольку оператор арифметического сложения является бинарным оператором, этот метод оператора принимает два входных параметра типа Vector2D
и возвращает одно выходное значение, также типа Vector2D
.
В этой реализации входные параметры имеют имена left
и right
представляют Vector2D
экземпляры, которые будут слева и справа от +
оператора. Метод возвращает новый Vector2D
экземпляр, у которого x
и y
свойств инициализируются с суммой x
и y
свойствами из двух Vector2D
экземпляров, которые добавляются вместе.
Метод type может использоваться как инфиксный оператор между существующими Vector2D
экземплярами:
let vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector
// combinedVector is a Vector2D instance with values of (5.0, 5.0)
В этом примере складываются векторы и получается вектор: (3.0, 1.0)
(2.0, 4.0)
(5.0, 5.0)
Префиксные и постфиксные операторы
Приведенный выше пример демонстрирует пользовательскую реализацию бинарного инфиксного оператора. Классы и структуры также могут предоставлять реализации стандартных унарных операторов . Унарные операторы работают на одну цель. Они являются префиксными, если они предшествуют своей цели (например, -a
), и постфиксными операторами, если они следуют своей цели (например, b!
).
Вы реализуете префиксный или постфиксный унарный оператор, написав модификатор prefix
or postfix
перед func
ключевым словом при объявлении метода оператора:
extension Vector2D {
static prefix func - (vector: Vector2D) -> Vector2D {
return Vector2D(x: -vector.x, y: -vector.y)
}
}
В приведенном выше примере реализован унарный оператор минус ( -a
) для Vector2D
экземпляров. Унарный оператор минус - это префиксный оператор, поэтому этот метод должен быть квалифицирован prefix
модификатором.
Для простых числовых значений унарный оператор минус преобразует положительные числа в их отрицательный эквивалент и наоборот. Соответствующая реализация для Vector2D
экземпляров выполняет эту операцию как для свойств, так x
и для y
:
let positive = Vector2D(x: 3.0, y: 4.0)
let negative = -positive
// negative is a Vector2D instance with values of (-3.0, -4.0)
let alsoPositive = -negative
// alsoPositive is a Vector2D instance with values of (3.0, 4.0)
Составные операторы присваивания
Составные операторы присваивания объединяют метод присвоения ( =
) с другой операцией. Например, оператор присваивания сложения ( +=
) объединяет сложение и присваивание в одну операцию. Вы помечаете левый тип входного параметра оператора сложного присваивания как inout
, потому что значение параметра будет изменено непосредственно из метода оператора.
В приведенном ниже примере реализован метод оператора сложения для Vector2D
экземпляров:
extension Vector2D {
static func += (left: inout 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
// original now has values of (4.0, 6.0)
ЗАМЕТКА
Невозможно перегрузить оператор присваивания по умолчанию (
=
). Только составные операторы присваивания могут быть перегружены. Аналогично, троичный условный оператор ( ) не может быть перегружен.a ? b : c
Операторы эквивалентности
По умолчанию пользовательские классы и структуры не имеют реализации операторов эквивалентности , известных как равные operator ( ==
) и не равныеoperator ( !=
). Обычно вы реализуете ==
оператор и используете стандартную реализацию !=
оператора по умолчанию, которая сводит на нет результат ==
оператора. Существует два способа реализации ==
оператора: вы можете реализовать его самостоятельно, или для многих типов вы можете попросить Swift синтезировать реализацию для вас. В обоих случаях вы добавляете соответствие стандартному Equatable
протоколу библиотеки .
Вы предоставляете реализацию ==
оператора так же, как и другие инфиксные операторы:
extension Vector2D: Equatable {
static func == (left: Vector2D, right: Vector2D) -> Bool {
return (left.x == right.x) && (left.y == right.y)
}
}
В приведенном выше примере реализован ==
оператор для проверки того, Vector2D
имеют ли два экземпляра эквивалентные значения. В контексте Vector2D
имеет смысл считать «равным» как означающее «оба экземпляра имеют одинаковые x
значения и y
значения», и поэтому это логика, используемая реализацией оператора.
Теперь вы можете использовать этот оператор, чтобы проверить, Vector2D
эквивалентны ли два экземпляра:
let twoThree = Vector2D(x: 2.0, y: 3.0)
let anotherTwoThree = Vector2D(x: 2.0, y: 3.0)
if twoThree == anotherTwoThree {
print("These two vectors are equivalent.")
}
// Prints "These two vectors are equivalent."
Во многих простых случаях вы можете попросить Swift предоставить вам синтезированные реализации операторов эквивалентности. Swift предоставляет синтезированные реализации для следующих типов пользовательских типов:
- Структуры, которые имеют только сохраненные свойства, соответствующие
Equatable
протоколу - Перечисления, имеющие только связанные типы, соответствующие
Equatable
протоколу - Перечисления, которые не имеют связанных типов
Чтобы получить синтезированную реализацию ==
, объявите Equatable
соответствие в файле, который содержит исходное объявление, без ==
самостоятельной реализации оператора.
Пример ниже определяет Vector3D
структуру для трехмерного вектора положения , подобную структуре. Поскольку , и свойства являются все из типа, получает синтезируются реализации операторов эквивалентности.(x, y, z)
Vector2D
x
y
z
Equatable
Vector3D
struct Vector3D: Equatable {
var x = 0.0, y = 0.0, z = 0.0
}
let twoThreeFour = Vector3D(x: 2.0, y: 3.0, z: 4.0)
let anotherTwoThreeFour = Vector3D(x: 2.0, y: 3.0, z: 4.0)
if twoThreeFour == anotherTwoThreeFour {
print("These two vectors are also equivalent.")
}
// Prints "These two vectors are also equivalent."
Таможенные операторы
Вы можете объявить и реализовать свои собственные пользовательские операторы в дополнение к стандартным операторам, предоставляемым Swift. Новые операторы объявляются на глобальном уровне с помощью operator
ключевого слова и помечаются модификаторами prefix
, infix
или postfix
:
prefix operator +++
В приведенном выше примере определяется новый префиксный оператор с именем +++
. Этот оператор не имеет существующего значения в Swift, поэтому ему дается свое собственное значение ниже в конкретном контексте работы с Vector2D
экземплярами. В этом примере +++
рассматривается как новый оператор удвоения префикса. Это удваивает x
и y
значение из , Vector2D
например, пути добавления вектора к себе с оператором присваивания дополнения , определенным ранее. Для реализации +++
оператора, можно добавить метод типа , называемый +++
в Vector2D
следующим образом :
extension Vector2D {
static prefix func +++ (vector: inout Vector2D) -> Vector2D {
vector += vector
return vector
}
}
var toBeDoubled = Vector2D(x: 1.0, y: 4.0)
let afterDoubling = +++toBeDoubled
// toBeDoubled now has values of (2.0, 8.0)
// afterDoubling also has values of (2.0, 8.0)
Приоритет для пользовательских инфиксных операторов
Каждый пользовательский инфиксный оператор принадлежит к группе приоритетов. Группа приоритетов определяет приоритет оператора относительно других инфиксных операторов, а также ассоциативность оператора.
Пользовательский инфиксный оператор, который явно не помещается в группу приоритетов, получает группу приоритетов по умолчанию с приоритетом, непосредственно превышающим приоритет тернарного условного оператора.
В следующем примере определяется новый пользовательский инфиксный оператор под названием +-
, который принадлежит к группе приоритетов AdditionPrecedence
:
infix operator +-: AdditionPrecedence
extension Vector2D {
static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y - right.y)
}
}
let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 4.0)
let plusMinusVector = firstVector +- secondVector
// plusMinusVector is a Vector2D instance with values of (4.0, -2.0)
Этот оператор складывает x
значения двух векторов и вычитает y
значение второго вектора из первого. Поскольку по сути это «аддитивный» оператор, ему была назначена та же группа приоритетов, что и у аддитивных инфиксных операторов, таких как +
и -
. Для получения информации об операторах, предоставляемых стандартной библиотекой Swift, включая полный список групп приоритетов операторов и параметров ассоциативности. Для получения дополнительной информации о группах приоритетов и для просмотра синтаксиса для определения ваших собственных операторов и групп приоритетов.
ЗАМЕТКА
Вы не указываете приоритет при определении префиксного или постфиксного оператора. Однако если к одному и тому же операнду применить оператор префикса и постфикса, сначала применяется оператор постфикса.
0 комментариев