Оператор является специальным символом или фразы , которую вы используете , чтобы проверить, изменить или скомбинировать значение. Например, оператор сложения ( +) добавляет два числа, как в , а логический оператор И ( ) объединяет два логических значения, как в .let i = 1 + 2&&if enteredDoorCode && passedRetinaScan

Swift поддерживает большинство стандартных операторов C и улучшает некоторые возможности для устранения распространенных ошибок кодирования. Оператор присваивания ( =) не возвращает значение, чтобы предотвратить его ошибочное использование, когда ==предполагается, что равно operator ( ). Арифметические операторы ( +-*/%и т.д.) обнаружить и запретить переполнение значения, чтобы избежать неожиданных результатов при работе с числами , которые становятся больше или меньше , чем диапазон допустимого значения типа , который хранит их. Вы можете выбрать поведение переполнения, используя операторы переполнения Swift, как описано в разделе «Операторы переполнения» .

Swift также предоставляет операторы диапазона, которых нет в C, такие как a..<bи a...b, в качестве ярлыка для выражения диапазона значений.

В этой главе описываются общие операторы в Swift. Расширенные операторыохватывают расширенные операторы Swift и описывают, как определять свои собственные пользовательские операторы и реализовывать стандартные операторы для собственных пользовательских типов.

Терминология

Операторы унарные, двоичные или троичные:

  • Унарные операторы работают на одну цель (например, -a). Унарные префиксныеоператоры появляются непосредственно перед их целью (например !b), а унарные постфиксные операторы появляются сразу после их цели (например c!).
  • Бинарные операторы работают с двумя целями (такими как ) и являются инфиксными, потому что они появляются между двумя целями.2 + 3
  • Тернарные операторы работают на три цели. Как и C, Swift имеет только один троичный оператор - троичный условный оператор ( ).a ? b : c

Значения, на которые влияют операторы, являются операндами . В выражении , то символ является бинарным оператором и его два операнда являются значениями и .1 + 2+12

Оператор присваивания

Оператор присваивания ( ) инициализирует или обновляет значение со значением :a = bab

let b = 10

var a = 5

a = b

// a is now equal to 10

Если правая часть присваивания представляет собой кортеж с несколькими значениями, его элементы можно разложить на несколько констант или переменных одновременно:

let (x, y) = (1, 2)

// x is equal to 1, and y is equal to 2

В отличие от оператора присваивания в C и Objective-C, оператор присваивания в Swift сам по себе не возвращает значение. Следующее утверждение недопустимо:

if x = y {

// This is not valid, because x = y does not return a value.

}

Эта функция предотвращает =случайное использование оператора присваивания ( ), когда ==фактически предполагается равенство с оператором ( ). Делая недействительным, Swift помогает вам избежать подобных ошибок в вашем коде.if x = y

Арифметические операторы

Swift поддерживает четыре стандартных арифметических оператора для всех типов чисел:

  • Дополнение ( +)
  • Вычитание ( -)
  • Умножение ( *)
  • Отдел ( /)
1 + 2 // equals 3

5 - 3 // equals 2

2 * 3 // equals 6

10.0 / 2.5 // equals 4.0

В отличие от арифметических операторов в C и Objective-C, арифметические операторы Swift не допускают переполнения значений по умолчанию. Вы можете выбрать поведение переполнения, используя операторы переполнения Swift (например, ). Смотрите Операторы переполнения .a &+ b

Оператор сложения также поддерживается для Stringобъединения:

"hello, " + "world" // equals "hello, world"

Оставшийся оператор

Оператор remainder ( ) определяет, сколько крат будет помещаться внутри, и возвращает оставшееся значение (известное как остаток ).a % bba

ЗАМЕТКА

Оператор остатка ( %) также известен как оператор по модулю в других языках. Однако его поведение в Swift для отрицательных чисел означает, что, строго говоря, это остаток, а не операция по модулю.

Вот как работает оператор остатка. Чтобы рассчитать , вы сначала определите, сколько s поместится внутри :9 % 449

Вы можете поместить два 4s внутри 9, а остальное 1(показано оранжевым цветом).

В Swift это будет записано как:

9 % 4 // equals 1

Чтобы определить ответ для , оператор вычисляет следующее уравнение и возвращает его результат:a % b%remainder

a= ( bх ) +some multiplierremainder

где наибольшее число, кратное тому, что поместится внутри .some multiplierba

Вставка 9и 4в это уравнение дает:

9= ( 4х 2) +1

Тот же метод применяется при расчете остатка для отрицательного значения a:

-9 % 4 // equals -1

Вставка -9и 4в уравнение дает:

-9= ( 4х -2) +-1

давая остаток стоимости -1.

Знак bигнорируется для отрицательных значений b. Это значит, что и всегда дают один и тот же ответ.a % ba % -b

Унарный минус оператор

Знак числового значения можно переключать с помощью префикса -, известного как унарный оператор минус :

let three = 3

let minusThree = -three // minusThree equals -3

let plusThree = -minusThree // plusThree equals 3, or "minus minus three"

Оператор унарного минуса ( -) добавляется непосредственно перед значением, с которым он работает, без пробелов.

Унар Плюс Оператор

Унарный плюс ( +) просто возвращает значение, которое действует на, без каких - либо изменений:

let minusSix = -6

let alsoMinusSix = +minusSix // alsoMinusSix equals -6

Хотя унарный оператор плюс на самом деле ничего не делает, вы можете использовать его, чтобы обеспечить симметрию в своем коде для положительных чисел, а также использовать унарный оператор минус для отрицательных чисел.

Составные операторы присваивания

Как и C, Swift предоставляет составные операторы присваивания, которые комбинируют метод assign ( =) с другой операцией. Одним из примеров является оператор присваивания ( +=):

var a = 1

a += 2

// a is now equal to 3

Выражение является сокращением для . По сути, сложение и назначение объединяются в одного оператора, который выполняет обе задачи одновременно.a += 2a = a + 2

ЗАМЕТКА

Составные операторы присваивания не возвращают значение. Например, вы не можете писать .let b = a += 2

Для получения информации об операторах, предоставляемых стандартной библиотекой Swift, см. Объявления операторов .

Операторы сравнения

Swift поддерживает все стандартные операторы сравнения C :

  • Равно ( )a == b
  • Не равно ( )a != b
  • Больше чем ( )a > b
  • Меньше чем ( )a < b
  • Больше или равно ( )a >= b
  • Меньше или равно ( )a <= b

ЗАМЕТКА

Swift также предоставляет два идентификатора оператора ( ===и !==), которые вы используете, чтобы проверить, ссылаются ли обе ссылки на один и тот же экземпляр объекта. Для получения дополнительной информации см. Identity Operators .

Каждый из операторов сравнения возвращает Boolзначение, чтобы указать, верно ли утверждение:

1 == 1 // true because 1 is equal to 1

2 != 1 // true because 2 is not equal to 1

2 > 1 // true because 2 is greater than 1

1 < 2 // true because 1 is less than 2

1 >= 1 // true because 1 is greater than or equal to 1

2 <= 1 // false because 2 is not less than or equal to 1

Операторы сравнения часто используются в условных выражениях, таких как if:

let name = "world"

if name == "world" {

print("hello, world")

} else {

print("I'm sorry \(name), but I don't recognize you")

}

// Prints "hello, world", because name is indeed equal to "world".

Для получения дополнительной информации об ifоператоре см. Поток управления .

Вы можете сравнить два кортежа, если они имеют одинаковый тип и одинаковое количество значений. Кортежи сравниваются слева направо, по одному значению за раз, пока сравнение не обнаружит два значения, которые не равны. Эти два значения сравниваются, и результат этого сравнения определяет общий результат сравнения кортежей. Если все элементы равны, то сами кортежи равны. Например:

(1, "zebra") < (2, "apple") // true because 1 is less than 2; "zebra" and "apple" are not compared

(3, "apple") < (3, "bird") // true because 3 is equal to 3, and "apple" is less than "bird"

(4, "dog") == (4, "dog") // true because 4 is equal to 4, and "dog" is equal to "dog"

В приведенном выше примере вы можете увидеть поведение сравнения слева направо в первой строке. Потому 1что меньше чем 2, считается меньше чем , независимо от любых других значений в кортежах. Неважно, что это не меньше , потому что сравнение уже определяется первыми элементами кортежей. Однако, когда первые элементы кортежей являются одинаковыми, их вторые элементы имеют по сравнению, это то , что происходит на второй и третьей линии.(1, "zebra")(2, "apple")"zebra""apple"

Кортежи можно сравнивать с данным оператором, только если оператор можно применить к каждому значению в соответствующих кортежах. Например, как показано в приведенном ниже коде, вы можете сравнить два кортежа типа, так как и значения, и значения можно сравнить с помощью оператора. Напротив, два кортежа типа не могут сравниваться с оператором, потому что оператор не может быть применен к значениям.(String, Int)StringInt<(String, Bool)<<Bool

("blue", -1) < ("purple", 1) // OK, evaluates to true

("blue", false) < ("purple", true) // Error because < can't compare Boolean values

ЗАМЕТКА

Стандартная библиотека Swift включает в себя операторы сравнения кортежей для кортежей, содержащих менее семи элементов. Чтобы сравнить кортежи с семью или более элементами, вы должны самостоятельно реализовать операторы сравнения.

Тернарный условный оператор

Тройной условный оператор является специальным оператором с тремя частями, который принимает форму . Это ярлык для оценки одного из двух выражений в зависимости от того, является ли оно истинным или ложным. Если это правда, он оценивает и возвращает свое значение; в противном случае он оценивает и возвращает свое значение.question ? answer1 : answer2questionquestionanswer1answer2

Тернарный условный оператор является сокращением для кода ниже:

if question {

answer1

} else {

answer2

}

Вот пример, который вычисляет высоту строки таблицы. Высота строки должна быть на 50 пунктов выше, чем высота содержимого, если строка имеет заголовок, и на 20 пунктов выше, если строка не имеет заголовка:

let contentHeight = 40

let hasHeader = true

let rowHeight = contentHeight + (hasHeader ? 50 : 20)

// rowHeight is equal to 90

Пример выше является сокращением для кода ниже:

let contentHeight = 40

let hasHeader = true

let rowHeight: Int

if hasHeader {

rowHeight = contentHeight + 50

} else {

rowHeight = contentHeight + 20

}

// rowHeight is equal to 90

В первом примере использование троичного условного оператора означает, что ему rowHeightможет быть задано правильное значение в одной строке кода, что является более кратким, чем код, использованный во втором примере.

Тернарный условный оператор обеспечивает эффективную стенограмму для решения, какое из двух выражений следует рассмотреть. Однако используйте троичный условный оператор с осторожностью. Его краткость может привести к сложному для чтения коду при чрезмерном использовании. Избегайте объединения нескольких экземпляров тернарного условного оператора в один составной оператор.

Ноль-коалесцирующий оператор

Оператор nil- coalescing ( ) разворачивает необязательное значение, если оно содержит значение, или возвращает значение по умолчанию, если оно есть . Выражение всегда имеет необязательный тип. Выражение должно соответствовать типу, который хранится внутри .a ?? babanilaba

Оператор nil-coalescing является сокращением для кода ниже:

a != nil ? a! : b

Приведенный выше код использует троичный условный оператор и принудительный unwrapping ( a!) для доступа к значению, заключенному внутри, aкогда aего нет nil, и для возврата в bпротивном случае. Оператор nil-coalescing предоставляет более элегантный способ инкапсулировать эту условную проверку и развертывание в сжатой и читаемой форме.

ЗАМЕТКА

Если значение не aявляется nil, значение bне оценивается. Это известно как оценка короткого замыкания .

В приведенном ниже примере оператор nil-coalescing выбирает имя цвета по умолчанию и необязательное имя цвета, определяемое пользователем:

let defaultColorName = "red"

var userDefinedColorName: String? // defaults to nil



var colorNameToUse = userDefinedColorName ?? defaultColorName

// userDefinedColorName is nil, so colorNameToUse is set to the default of "red"

userDefinedColorNameПеременная определяется как необязательный String, со значением по умолчанию nil. Поскольку userDefinedColorNameэто необязательный тип, вы можете использовать оператор nil-coalescing, чтобы рассмотреть его значение. В приведенном выше примере оператор используется для определения начального значения для Stringвызываемой переменной colorNameToUse. Потому userDefinedColorNameчто nil, выражение возвращает значение или .userDefinedColorName ?? defaultColorNamedefaultColorName"red"

Если вы назначите ненулевое nilзначение и снова userDefinedColorNameвыполните проверку оператора nil-coalescing, userDefinedColorNameвместо значения по умолчанию используется значение, заключенное внутри :

userDefinedColorName = "green"

colorNameToUse = userDefinedColorName ?? defaultColorName

// userDefinedColorName is not nil, so colorNameToUse is set to "green"

Операторы диапазона

Swift включает в себя несколько операторов диапазона , которые являются ярлыками для выражения диапазона значений.

Закрытый оператор

Диапазон оператор замкнутого ( a...b) определяет диапазон , который проходит от aдо b, и включает в себя значения aи b. Значение aне должно быть больше чем b.

Оператор закрытого диапазона полезен при итерации по диапазону, в котором вы хотите использовать все значения, например, с циклом forin:

for index in 1...5 {

print("\(index) times 5 is \(index * 5)")

}

// 1 times 5 is 5

// 2 times 5 is 10

// 3 times 5 is 15

// 4 times 5 is 20

// 5 times 5 is 25

Более подробную информацию о forinпетлями см Flow Control .

Оператор полуоткрытого диапазона

Оператор полуоткрытого диапазона ( a..<b) определяет диапазон, который работает от aдо b, но не включает в себя b. Говорят, что он наполовину открыт, потому что содержит его первое значение, но не его окончательное значение. Как и в случае с оператором закрытого диапазона, значение aне должно быть больше, чем b. Если значение aравно b, то результирующий диапазон будет пустым.

Полуоткрытые диапазоны особенно полезны, когда вы работаете со списками, начинающимися с нуля, такими как массивы, где полезно подсчитывать (но не включая) длину списка:

let names = ["Anna", "Alex", "Brian", "Jack"]

let count = names.count

for i in 0..<count {

print("Person \(i + 1) is called \(names[i])")

}

// Person 1 is called Anna

// Person 2 is called Alex

// Person 3 is called Brian

// Person 4 is called Jack

Обратите внимание, что массив содержит четыре элемента, но 0..<countсчитается только до 3(индекс последнего элемента в массиве), потому что это полуоткрытый диапазон. Для получения дополнительной информации о массивах см. Массивы .

Односторонние ряды

Оператор закрытого диапазона имеет альтернативную форму для диапазонов, которые продолжаются, насколько это возможно, в одном направлении, например, диапазон, который включает все элементы массива от индекса 2 до конца массива. В этих случаях вы можете опустить значение с одной стороны оператора диапазона. Этот вид диапазона называется односторонним диапазоном, потому что оператор имеет значение только с одной стороны. Например:

for name in names[2...] {

print(name)

}

// Brian

// Jack



for name in names[...2] {

print(name)

}

// Anna

// Alex

// Brian

Оператор полуоткрытого диапазона также имеет одностороннюю форму, написанную только с его конечным значением. Так же, как когда вы включаете значение с обеих сторон, окончательное значение не входит в диапазон. Например:

for name in names[..<2] {

print(name)

}

// Anna

// Alex

Односторонние диапазоны могут использоваться в других контекстах, а не только в подписках. Вы не можете выполнять итерацию по одностороннему диапазону, в котором пропущено первое значение, потому что неясно, где должна начинаться итерация. Вы можете перебирать односторонний диапазон, в котором не указывается его окончательное значение; однако, поскольку диапазон продолжается бесконечно, убедитесь, что вы добавили явное конечное условие для цикла. Вы также можете проверить, содержит ли односторонний диапазон конкретное значение, как показано в приведенном ниже коде.

let range = ...5

range.contains(7) // false

range.contains(4) // true

range.contains(-1) // true

Логические Операторы

Логические операторы изменяют или объединяют значения логической логики trueи false. Swift поддерживает три стандартных логических оператора в языках на основе C:

  • Логическое НЕ ( !a)
  • Логическое И ( )a && b
  • Логическое ИЛИ ( )a || b

Логическое НЕ Оператор

Логический оператор НЕ ( !a) инвертирует логическое значение , таким образом , что trueстановится false, и falseстановится true.

Логический оператор NOT является префиксным оператором и появляется непосредственно перед значением, с которым он работает, без пробелов. Его можно прочитать как «нет a», как показано в следующем примере:

let allowedEntry = false

if !allowedEntry {

print("ACCESS DENIED")

}

// Prints "ACCESS DENIED"

Фраза может быть прочитана как «если недопустимая запись». Следующая строка выполняется только в том случае, если «недопустимая запись» имеет значение true; если есть .if !allowedEntryallowedEntryfalse

Как и в этом примере, тщательный выбор логических констант и имен переменных может помочь сделать код читаемым и кратким, избегая двойных отрицаний или запутанных логических выражений.

Логический И Оператор

Логический оператор ( ) создает логические выражения , где оба значения должны быть для всего выражения также быть .a && btruetrue

Если любое значение равно false, общее выражение также будет false. Фактически, если первое значение равно false, второе значение даже не будет оцениваться, потому что оно не может сделать общее выражение равным true. Это известно как оценка короткого замыкания .

В этом примере рассматриваются два Boolзначения и разрешается доступ только в том случае, если оба значения true:

let enteredDoorCode = true

let passedRetinaScan = false

if enteredDoorCode && passedRetinaScan {

print("Welcome!")

} else {

print("ACCESS DENIED")

}

// Prints "ACCESS DENIED"

Оператор логического ИЛИ

Оператор логического ИЛИ ( ) - это инфиксный оператор, состоящий из двух соседних символов канала. Вы используете его для создания логических выражений, в которых должно быть только одно из двух значений для общего выражения .a || btruetrue

Как и оператор логического И выше, оператор логического ИЛИ использует оценку короткого замыкания для рассмотрения его выражений. Если левая сторона выражения логического ИЛИ равна true, правая сторона не оценивается, потому что она не может изменить результат всего выражения.

В приведенном ниже примере первое Boolзначение ( hasDoorKey) есть false, а второе значение ( knowsOverridePassword) есть true. Поскольку одно значение - trueобщее выражение также оценивается true, и доступ разрешен:

let hasDoorKey = false

let knowsOverridePassword = true

if hasDoorKey || knowsOverridePassword {

print("Welcome!")

} else {

print("ACCESS DENIED")

}

// Prints "Welcome!"

Объединение логических операторов

Вы можете объединить несколько логических операторов для создания более длинных составных выражений:

if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {

print("Welcome!")

} else {

print("ACCESS DENIED")

}

// Prints "Welcome!"

В этом примере используются несколько операторов &&и ||операторы для создания более длинного составного выражения. Тем не менее, &&и ||операторы по- прежнему работают только два значения, так что это на самом деле три меньших выражения прикован вместе. Пример можно прочитать как:

Если мы ввели правильный код двери и прошли сканирование сетчатки, или у нас есть действующий ключ от двери, или если мы знаем пароль аварийного отмены, тогда разрешите доступ.

На основании значений enteredDoorCodepassedRetinaScanи hasDoorKeyпервые два подвыражения false. Однако пароль аварийного переопределения известен, поэтому общее составное выражение все равно оценивается как true.

ЗАМЕТКА

Логические операторы Swift &&и ||являются левоассоциативными, это означает, что составные выражения с несколькими логическими операторами сначала оценивают крайнее левое подвыражение.

Явные круглые скобки

Иногда полезно включать скобки, когда они не являются строго необходимыми, чтобы облегчить чтение намерения сложного выражения. В приведенном выше примере доступа к двери полезно добавить круглые скобки вокруг первой части составного выражения, чтобы сделать его намерение явным:

if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {

print("Welcome!")

} else {

print("ACCESS DENIED")

}

// Prints "Welcome!"

Скобки проясняют, что первые два значения рассматриваются как часть отдельного возможного состояния в общей логике. Вывод составного выражения не меняется, но общее намерение становится понятнее читателю. Читаемость всегда предпочтительнее краткости; используйте скобки, где они помогают прояснить ваши намерения.