Урок 2.7 Циклы

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

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


Что Вы Узнаете

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

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


Связанные Ресурсы

Руководство по языку программирования Swift: Циклы For-in, Циклы While
Руководство по языку программирования Swift: Операторы диапазона

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

Цикл for

Первый цикл, который вы изучите, - это цикл for, также известный более конкретно как цикл for-in. Цикл for полезен для повторения чего-либо заданное количество раз или для выполнения работы с набором значений.

Цикл for-in выполняет набор инструкций для каждого элемента в пределах диапазона, последовательности или коллекции. Предположим, у вас есть диапазон чисел от 1 до 5, и вы хотите напечатать каждое значение в пределах этого диапазона. Вместо того чтобы выписывать пять инструкций print, вы можете использовать for-in по всему диапазону и написать одну инструкцию print. Синтаксис выглядит следующим образом:

 

for index in 1...5 {
  print(”This is number \(index)”)
}


Console Output:
This is number 1
This is number 2
This is number 3
This is number 4
This is number 5

 

Тот самый ... известен как оператор закрытого диапазона, который позволяет определить диапазон значений, который простирается от x до y и включает в себя как x, так и y в диапазоне. Существует сопутствующий оператор (..<), известный как оператор полуоткрытого диапазона. Эти диапазоны простираются от x до y, но не включают y.

В приведенном выше коде index - это константа, доступная для настройки работы, выполняемой в фигурных скобках (цикл for-in). При первом выполнении инструкции в фигурных скобках index имеет значение 1, первое значение в диапазоне. Когда выполнение завершено, значение index обновляется до 2, следующего значения в диапазоне. Поскольку index обновляется до каждого из значений, оператор print выполняется пять раз. После того, как весь диапазон исчерпан, цикл завершен, и код переходит к операторам после цикла. 

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

 

for _ in 1...3 {
  print(”Hello!”)
}


Console Output:
Hello!
Hello!
Hello!
 

Вы можете использовать тот же синтаксис for-in для перебора каждого элемента в массиве.


let names = [”Joseph”, “Cathy”, “Winston”]
for name in names {
  print(”Hello \(name)”)
}


Console Output:
Hello Joseph
Hello Cathy
Hello Winston

 

Поскольку String - это тип коллекции, он обладает аналогичной функциональностью с массивом. Вы можете использовать цикл for-in для перебора каждого символа в строке:

 

for letter in “ABCD” {
  print(”The letter is \(letter)”)
}


Console Output:
The letter is A
The letter is B
The letter is C
The letter is D

 

Что делать, если вам нужен индекс каждого элемента в дополнение к его значению? Вы можете использовать метод enumerated() массива или строки для возврата кортежа — специального типа, который может содержать упорядоченный список значений, заключенных в круглые скобки, — содержащий как индекс, так и значение каждого элемента:

 

for (index, letter) in “ABCD”.enumerated() {
  print(”\(index): \(letter)”)
}


Console Output:
0: A
1: B
2: C
3: D

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

 

let animals = ["Lion", "Tiger", "Bear"]
for index in 0..<animals.count {
  print("\(index): \(animals[index])")
}


Console Output:
0: Lion
1: Tiger
2: Bear

 

Если вы используете цикл for-in со словарем, цикл генерирует кортеж, содержащий ключ и значение каждой записи. Поскольку доступ к словарю обычно осуществляется путем указания ключа, цикл не гарантирует какого-либо определенного порядка элементов при работе со словарем:

 

let vehicles = [”unicycle”: 1, “bicycle”: 2, “tricycle”: 3, “quad bike”: 4
for (vehicleName, wheelCount) in vehicles {
  print(”A \(vehicleName) has \(wheelCount) wheels”)
}


Console Output:
A unicycle has 1 wheels
A bicycle has 2 wheels
A tricycle has 3 wheels
A quad bike has 4 wheels

 

Цикл while

Цикл while будет продолжаться до тех пор, пока его указанное условие больше не будет выполнено. Представьте, что вы хотите продолжать играть в игру, пока у вас не кончатся “жизни”. Условие, при котором вы продолжаете цикл, заключается в том, что количество жизней больше 0:

 

var numberOfLives = 3
 
while numberOfLives > 0 {
  playMove()
  updateLivesCount()
}

 

Swift проверяет условие перед выполнением каждого цикла, что означает, что можно полностью пропустить цикл, если условие никогда не выполняется. Если бы numberOfLives был инициализирован в 0 в приведенном выше примере, цикл while определил бы, что 0 > 0 равно false, и никогда не переходил бы к телу цикла.

По этой причине тело цикла while должно выполнять работу, которая в конечном итоге изменит условие. В приведенном ниже примере ничто не обновляет значение numberOfLives, поэтому условие всегда принимает значение true и продолжается вечно.

 

var numberOfLives = 3
 
while numberOfLives > 0 {
  print(”I still have \(numberOfLives) lives.”)
}

 

Вместо этого тело должно выполнять инструкции, которые в какой-то момент приведут к ложному условию:

 

var numberOfLives = 3
var stillAlive = true
while stillAlive {
  numberOfLives -= 1
  if numberOfLives == 0 {
    stillAlive = false
  }
}

 

Цикл Repeat-While

Цикл repeat-while аналогичен циклу while, но этот синтаксис выполняет блок один раз перед проверкой условия.

var steps = 0
let wall = 2 // there's a wall after two steps
 
repeat {
  print("Step")
 
  steps += 1
 
  if steps == wall {
    print("You've hit a wall!")
    break
  }
} while steps < 10 // maximum in this direction


Console Output:
Step
Step
You've hit a wall!

 

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

У вас могут возникнуть ситуации, когда вы хотите остановить выполнение цикла из тела цикла. Ключевое слово break в языке Swift прерывает выполнение кода в цикле и запускает выполнение любого кода, определенного после цикла (вы можете узнать это из инструкции switch).
В приведенном ниже коде цикл прерывается, если счетчик достигает 0:


 
//  Выводит от -3 до 0
for counter in -3...3 {
  print(counter)
  if counter == 0 {
    break
  }
}


Console Output:
-3
-2
-1
0

 

Также могут быть ситуации, в которых вы хотите перейти к следующей итерации в цикле. В то время как ключевое слово break полностью завершит цикл, continue перейдет к следующей итерации. Например, у вас может быть массив, где каждый элемент имеет тип Person, и вы хотите перебрать массив и отправить электронное письмо всем лицам в возрасте 18 лет и старше:

 

for person in people {
  if person.age < 18 {
    continue
  }
 
  sendEmail(to: person)
}

 

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

Лабораторная работа

Откройте и завершите упражнения в Lab—Loops.playground.

Подключение к дизайну

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

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

 


Отрывок из книги
Develop in Swift Fundamentals
Apple Education
https://books.apple.com/ru/book/develop-in-swift-fundamentals/id1581182804

Information

Apple, the Apple logo, Apple Books, Apple TV, Apple Watch, Cocoa, Cocoa Touch, Finder, Handoff, HealthKit, iPad, iPad Pro, iPhone, iPod touch, Keynote, Mac, macOS, Numbers, Objective-C, Pages, Photo Booth, Safari, Siri, Spotlight, Swift, tvOS, watchOS, and Xcode are trademarks of Apple Inc., registered in the U.S. and other countries. App Store and iBooks Store are service marks of Apple Inc., registered in the U.S. and other countries. ​
The Bluetooth® word mark and logos are registered trademarks owned by Bluetooth SIG, Inc. and any use of such marks by Apple is under license. ​
IOS is a trademark or registered trademark of Cisco in the U.S. and other countries and is used under license. ​
Other product and company names mentioned herein may be trademarks of their respective companies.