Урок 6. Тернарный оператор

1 Ноября 2022

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

Это достаточно простая концепция, особенно если вы хорошо разобрались в условной конструкции if. 

Давайте для начала посмотрим на синтаксис конструкции

условие ? Действие если условие true : Действие если условие false

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

Прежде чем посмотреть на примере работу данного оператора, давайте начнем с привычной нам условной конструкции if:

				
					let name = "Sem"
if name != "Sem" {
    print("Who are you?")
} else {
    print("Hello, \(name)")
}
				
			

Давайте проговорим как отработает компилятор. Он видит ключевое слово if, понимает что это начало условной конструкции, после ключевого слова, он проверяет условие name != “Sem” если оно возвращает true то компилятор выполнит блок кода в фигурных скобках, после условия. 

В нашем случае условие вернет false, потому что имя равно “Sam”, а мы проверяем на не равенство, то есть если name не равно “Sam” то возвращается true. Значит первое условие не выполняется и блок кода в фигурных скобках после условия не выполнится, и компилятор идет к следующей ветке else, так как там нет условия, то блок кода после else будет выполнен. 

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

Тернарный оператор по сути является краткой формой if/else конструкции.

Первым идет условие:

				
					name != "Sem"
				
			

После мы должны поставить вопросительный знак:

				
					name != "Sem" ? 
				
			

Далее, действие, которое должно быть выполнено в случае, если условие возвращает true, в нашем случае это фраза Who are you?:

				
					name != "Sem" ? print("who are you?") 
				
			

Далее нам нужно поставить двоеточие, и определить действие, которое будет отрабатывать в том случае, если условие вернет false:

				
					name != "Sem" ? print("who are you?") : print("Hello, \(name)")
				
			

Хорошо, с этим мы разобрались, но давайте рассмотрим еще одну конструкцию if:

				
					var count = 0

if count < 5 {
    count += 1
} else {
    count -= 1
}
				
			

count += 1 это сокращенная форма от count = count + 1

Если свойство count меньше 5 то, мы прибавляем единицу, иначе мы вычитаем единицу. 

Давайте теперь попробуем сделать тоже самое, но с использованием тернарного оператора. По логике мы должны сделать следующим образом:

				
					var count = 0

count < 5 ? count += 1 : count -= 1
				
			

Но если мы запустим компилятор, то он нам выдаст ошибку. Потому что мы не можем в тернарном операторе делать присвоение (=). Но мы можем делать математические операции:

				
					var count = 0

count < 5 ? count + 1 : count - 1
				
			

Так на нас не будет ругаться компилятор, и даже выдаст результат:

то есть если count < 5 то сработает первое действие 0 + 1. И если мы с права видим результат то его мы можем присвоить новому свойству:

				
					var count = 0

let result = count < 5 ? count + 1 : count - 1
				
			

Теперь result будет содержать эту единичку. но нам же нужно что бы count обновился, поэтому мы можем этот результат передать в count:

Как вы можете видеть, свойство count теперь содержит в себе значение 1. 

Но давайте подумаем как мы можем еще сократить данную конструкцию, и начнем мы с изменения нашей условной конструкции:

				
					var count = 0

count < 5 ? 1 : -1
				
			

Если у нас условие возвращает true, то конструкция вернет 1, иначе -1. и эти значения мы можем присвоить новому свойству, и наше свойство, в зависимости от условия, будет содержать либо 1 либо -1:

Давайте для лучшего понимания, нарушим условие, и присвоим значение 6 нашему свойству count, в таком случае свойство result будет содержать -1:

Теперь понимая процесс получения результата, мы его можем прибавить к нашему свойству count:

то есть тернарная условная конструкция вернет нам либо 1 либо -1, и мы это значение прибавим к свойству count.

Область видимости

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

Давайте создадим простую условную конструкцию:

				
					let name = "Sem"
var count = 0

if name == "Sem" {
    let levelOne = "Зона 1"
    print("\(name) в \(levelOne)")
}
				
			

Если имя равно “Sem” то мы создаем новое свойство и выводим на консоль фразу “Sem в Зона 1”

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

Давайте теперь попробуем вынести принт за пределы этой зоны:

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

				
					let name = "Sem"
var count = 0

if name == "Sem" {
    let levelOne = "Зона 1"
    if count == 0 {
        let levelTwo = "Зона 2"
        print("Эта зона видит и \(name) и \(levelOne) и \(levelTwo)")
    }
    print("\(name) в \(levelOne)")
}
				
			

Давайте посмотрим где начинается и где заканчивается эта новая зона:

Эта зона видит все что происходит выше по иерархии, она видит свойство levelOne, она видит name. 

Давайте выделим первую локальную зону:

Эта зона видит все что находится выше, но не видит свои внутренние зоны, то есть свойство levelTwo она не видит, что бы в этом убедится, нужно просто вынести принт на уровень выше:

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

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

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

Давайте подведем итог, в playground мы пишем весь код в глобальной зоне, когда мы прописываем фигурные скобки то мы создаем локальную зону (нашу коробку из примера выше).

Вот первая коробка:


А внутри нее вторая коробка: