# Новые инструкции

# Цикл Для

Полностью аналогичен циклу for в JavaScript (opens new window):

Для(<инициализация>; <условие-завершения>; <шаг-цикла>)
   <тело-цикла>

В блоке <инициализация> можно объявлять и инициализировать переменную, по которой идет цикл. <Условие-завершения> является логическим выражением: когда оно становится ложным, цикл завершается. Выражение <шаг-цикла> должно изменять переменную цикла. <инициализация> выполняется один раз перед началом цикла, два других выражения - на каждой итерации; любое из них можно опустить.

Примеры:

перем м = @[]
Для(перем сч = 1; сч <= 5; сч++)
   м.Добавить(сч)
# теперь м содержит числа от одного до пяти

# вечный цикл
Для(;;)
   Пауза(100)

Ссылка на документацию.

# Продолжить

Во всех типах циклов можно использовать инструкцию Продолжить, которая завершает текущую итерацию цикла и переходит на новую:

перем м = @[]
Для(перем сч = 1; сч <= 10; сч++)
{
   Если(сч % 2 == 0)
      Продолжить
   м.Добавить(сч)
}
# м содержит все нечетные числа
# в диапазоне от 1 до 10

# Инструкция Удалить

Аналог инструкции delete в JavaScript (opens new window). Позволяет удалить переменную или элемент коллекции по имени. Если такой переменной или элемента нет, то не выполняет никаких действий.

перем п = 1
перем о = @{x: 1, y: 2}

Удалить п
Удалить о.x

# Итераторы и цикл ДляВсех

Итератором называется объект с двумя методами ЕстьСледующий и Следующий. Он представляет собой абстрактную последовательность значений (элементов массива, записей объекта, файлов в папке и т.п.), которую можно обойти в цикле (на примере массива):

 # получаем итератор
перем ит = @["а", "б", "в"].Итератор()

Пока(ит.ЕстьСледующий())
{
   перем эл = ит.Следующий()
   Консоль.Лог(эл)
}
# печатает в консоли
# а
# б
# в

Метод ЕстьСледующий возвращает true, если в последовательность еще остались элементы, а метод Следующий - текущий элемент последовательности и переходит к следующему. Многие встроенные типы данных (объекты, массивы, строки и др.) предоставляют итераторы, поэтому для работы с ними добавлен специальный цикл

ДляВсех(<имя-переменной> в <итератор-или-коллекция>)
   <тело-цикла>

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

# обход элементов объекта
# итератор создается неявно
ДляВсех(эл в @{x: 1, y: 2})
   Консоль.Лог(
      "Ключ = " + эл.ключ + ",
      Значение = " + эл.значение
   )
# напечатает в консоли
# Ключ = x, Значение = 1
# Ключ = y, Значение = 2


# обход элементов массива в прямом порядке
# итератор создается неявно
ДляВсех(эл в @["a", "б"])
   Консоль.Лог("Значение = " + эл)
# напечатает в консоли
# Значение = а
# Значение = б

# обход элементов массива в обратном порядке
# итератор создан явно
ДляВсех(эл в @["a", "б"].ОбратныйИтератор())
   Консоль.Лог("Значение = " + эл)
# напечатает в консоли
# Значение = б
# Значение = а

Во время обхода коллекции нельзя добавлять или удалять из нее элементы, это приведет к исключению

перем о = @{x: 1, y: 2, z: 3}
ДляВсех(эл в о)
   Если(эл.значение == 2)
      Удалить о[эл.ключ]      # исключение, нельзя изменять
                              # коллекцию в цикле по ее элементам

Значения элементов менять можно

перем о = @{x: 1, y: 2, z: 3}
ДляВсех(эл в о)
   Если(эл.значение == 2)
      о[эл.ключ] = 4

# Инструкция Попытка

В этой инструкции появилась дополнительная ветвь Заключение, которая вызывается всегда, независимо от того, возникло исключение или нет (аналог finally в JavaScript (opens new window)):

# строка "Заключение" будет напечатана
# в консоль в обоих случаях


Попытка
{
   ВызватьИсключение "Ошибка"
}
Исключение(e)
{
   Консоль.Лог(e)
}
Заключение
{
   Консоль.Лог("Заключение")
}


Попытка
{
   // исключения нет
}
Заключение
{
   Консоль.Лог("Заключение")
}

Кроме того, теперь в ветви Исключение можно опускать имя переменной для хранения объекта исключения, если он не нужен:

Попытка
{
   ВызватьИсключение "Ошибка"
}
Исключение
{
   Консоль.Лог("Произошла ошибка")
}