Выражения - конструкции языка, которым
может быть присвоено значение (константы,
переменной, функции и т.д.), и которые могут объединяться для создания "больших" выражений. Язык программирования JavaFX Script - это язык выражений, и поэтому все языковые конструкции, включая циклы, условия и даже блоки, являются выражениями. В некоторых случаях (например, цикл while ) выражения имеют тип Void , т.е. они не возвращают результирующее значение. |
Содержание
Блоковое выражение состоит из списка описаний и выражений, взятых в фигурные скобки и разделенных точками с запятой.
Значение блокового выражения определяется значением его последнего выражения. Блоковое выражение имеет тип Void в том случае, если оно не cодержит выражений. Обратите внимание, что var и def
являются выражениями.
Следующее блоковое выражение добавляет несколько числовых значений и сохраняет их в переменной total :
var nums = [5, 7, 3, 9];
var total = {
var sum = 0;
for (a in nums) { sum += a };
sum;
}
println("Total is {total}.");
|
После запуска этого скрипта мы получаем следующий результат:
Первая строка (var nums = [5, 7, 3, 9]; ) объявляет последовательность целых чисел.
Следующая строка кода объявляет переменную total,
которая будет хранить сумму этих целых чисел.
Блоковое выражение заключается в фигурные скобки:
{
var sum = 0;
for (a in nums) { sum += a };
sum;
}
|
Внутири этого блока, первая строка объявляет переменную sum для хранения суммы чисел этой последовательности. Вторая строка (выражение expression) организует цикл и добавляет каждое число к значению переменой sum . Последняя строка устанавливает возвращаемое значение блокового выражения (в нашем случае - 24).
Выражение if определяет направление хода программы, исполняя конкретный блок только в том случае, если значение заданного условия истинно.
Например, приведенный ниже скрипт, устанавливает цену билета в зависимости от возраста. Людям 12 до 65 лет билет продается по обычной цене - 10 долларов. Для детей и пенсионеров билет стоит 5 долларов, а дети до 5 лет проходят бесплатно.
def age = 8;
var ticketPrice;
if (age < 5 ) {
ticketPrice = 0;
} else if (age < 12 or age > 65) {
ticketPrice = 5;
} else {
ticketPrice = 10;
}
println("Age: {age} Ticket Price: {ticketPrice} dollars.");
|
Если значение переменной age равно 8, результат работы скрипта будет следующим:
Age: 8 Ticket Price: 5 dollars.
|
Ход программы в этом случае показан жирным шрифтом:
if (age < 5 ) {
ticketPrice = 0;
} else if (age > 5 and age < 12) {
ticketPrice = 5;
} else {
ticketPrice = 10;
}
|
Если значение переменной age меньше 5, стоимоcть билета равна 0.
Программа просто перескакивает проверки оставшихся условий и сразу переходит к печати результата.
Если значение возраста не меньше 5,
программа переходит к проверке следующего условия (обозначеного зарезервированным словом else и еще одним выражением
if ):
if (age < 5 ) {
ticketPrice = 0;
} else if (age > 5 and age < 12) {
ticketPrice = 5;
} else {
ticketPrice = 10;
}
|
Это выражение устанавливает цену билета равной 5 для людей, чей возраст от 5 до 12.
Если возраст равен 12 или больше, программа переходит к последнему блоку кода, обозначенному с помощью зарезервированного слова else :
if (age < 5 ) {
ticketPrice = 0;
} else if (age > 5 and age < 12) {
ticketPrice = 5;
} else {
ticketPrice = 10;
}
|
Этот блок исполняется только в том случае, если предыдущие условия не были выполнены. Этот блок устанавливает обычную цену билета 10 долларов для людей от 12 и старше.
Примечание: Предыдущий код может быть записан с помощью сокращенной формы условного выражения:
ticketPrice = if (age < 5) 0 else if (age > 5 and age < 12) 5 else 10;
|
Это очень полезный прием. Возьмите его на заметку, т.к. он еще будет использоваться в наших последующих уроках.
Из урока Последовательности вы могли запомнить короткую нотацию, используемую для объявления последовательности чисел в виде арифметического ряда:
Технически [0..5] является интервальным выражением. По умолчанию, интервал между значениями равен 1, но вы можете использовать зарезервированное слово step для того, чтобы задать другое значение интервала. Например, для определения последовательности, состоящей из нечетных чисел от одного до 10, будет использован следующий фрагмент кода:
var nums = [1..10 step 2];
println(nums);
|
Результат работы этой программы будет следующим:
Для создания убывающей последовательности, необходимо убедиться, что второе значение меньше, чем первое, и установить отрицательный шаг.
var nums = [10..1 step -1];
println(nums);
|
Мы получим следующий результат:
[ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
|
Если вы не указываете отрицательный шаг при создании убывающей последовательности, это привет к созданию пустой последовательности. Например, как показано на следующем фрагменте кода:
var nums = [10..1 step 1];
println(nums);
|
Этот код может вызвать предупреждающее сообщение при компиляции:
range.fx:1: warning: empty sequence range literal, probably not what you meant.
var nums = [10..1 step 1];
^
1 warning
|
Вы таже можете получить пустую последовательность, если вообще не укажете зарезервированное слово step .
Выражение for является еще одним выражением, имеющим отношение к последовательностям. Оно предоставляет удобный механизм для создания цикла при обработке элементов последовательности.
Рассмотрим следующий пример кода:
var days = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];
for (day in days) {
println(day);
}
|
Результатом работы такой программы будет:
Mon
Tue
Wed
Thu
Fri
Sat
Sun
|
Давайте детально рассмотрим это пример. Выражение for начинается с зарезервированного слова "for" :
for (day in days) {
println(day);
}
|
Переменная days представляет собой входную последовательность для обработки в цикле:
for (day in days) {
println(day);
}
|
Переменная day хранит значение текущего элемента последовательности при обработке в цикле for :
for (day in days) {
println(day);
}
|
Обратите внимание, что переменная day не была объявлена в нашем скрипте перед использованием в выражении for . Мы не сможем использовать ее после выхода из цикла.
Программисты часто используют для таких временных переменных очень короткие (или состоящие из одной буквы) имена.
В предыдущем примере, выражение for не возвращало значение;
тем не менее, это выражение возвращает последовательность. Следующий код показывает два примера создания последовательности из другой последовательности с использованием выражения for :
// Resulting sequence squares the values from the original sequence.
var squares = for (i in [1..10]) i*i;
// Resulting sequence is ["MON", "TUE", "WED", and so on...]
var capitalDays = for (day in days) day.toUppercase();
|
Обратите внимание, что у объекта String есть функция toUppercase . Вы сможете найти полный список всех доступных функций в
API (Application Programming Interface) документации.
Еще одной циклической конструкцией является выражение while. В отличие от выражения for ,
которое работает с элементами последовательности, выражение while создает цикл, выполняемый до тех пор, пока проверяемое условие не станет ложным (примет значение false ).
По своему синтаксису while является выражением, имеющим тип
Void , т.е оно не возвращает значение.
Рассмотрим пример:
var count = 0;
while (count < 10) {
println("count == {count}");
count++;
}
|
Результат работы этого примера будет следующим:
count == 0
count == 1
count == 2
count == 3
count == 4
count == 5
count == 6
count == 7
count == 8
count == 9
|
Первая строка объявляет переменную count и присваивает ей значение 0:
var count = 0;
while (count < 10) {
println("count == {count}");
count += 1;
}
|
В следующей строке начинается выражение while . Это выражение создает цикл (между открывающимися и закрывающимися скобками) который действует до тех пор, пока count < 10 :
var count = 0;
while (count < 10) {
println("count == {count}");
count += 1;
}
|
В теле цикла происходит вывод на консоль текущего значения переменной count и последующее увеличение его на единицу:
var count = 0;
while (count < 10) {
println("count == {count}");
count += 1;
}
|
Когда значение переменной count становится равным 10, происходит выход из цикла. Для создания бесконечного цикла используйте зарезервированное слово true , заключенное в круглые скобки: while(true){}
Выражения break и continue также имеют отношение к циклу.
Эти два выражения влияют на текущую итерацию цикла:
break прекращает цикл полностью, в то время как continue прекращает только текущую итерацию.
Поскольку break и continue синтаксически являются выражениями, они имеют тип Void и не возвращают значение.
Пример:
for (i in [0..10]) {
if (i > 5) {
break;
}
if (i mod 2 == 0) {
continue;
}
println(i);
}
|
Результат:
Без выражений if , программа просто выводила бы числа от 0 до 10.
Без первого выражения if ,
программа бы выходила из цикла в тот момент, когда i становится больше пяти:
Таким образом, программа выводила бы на консоль числа от 1 до 5.
С добавлением второго выражения if ,
программа прерывает только текущую итерацию цикла и переходит к продолжению следующей итерации:
if (i mod 2 == 0) {
continue;
}
|
В нашем примере continue выполняется только тогда, когда i является четным числом (т.е. делится на 2 без остатка). Когда это происходит программа не доходит до вызова метода println() , и соответствующие числа не выводятся на консоль.
В реальных приложения, возникают ситуации когда некоторые события нарушают нормальное течение выполнения скрипта. Например, если скрипт осуществляет чтение данных из файла, и этот файл не может быть открыт, скрипт не может продолжать свою работу. Такая ситуация называется исключением.
Примечание: Исключения являются объектами. Их типы носят имена тех условий, которые их вызвали (например, FileNotFoundException обозначает условие, когда файл на может быть найден). Однако, в наших примерах мы не будем рассматривать какие-либо специфические исключения. Это будет объект
Exception общего назначения, позаимствованный нами из языка программирования Java. На его примере мы рассмотрим выражения
throw , try , catch , и
finally .
Следующий скрипт определяет и вызывает функцию, которая бросает исключение:
import java.lang.Exception;
foo();
println("The script is now executing as expected... ");
function foo() {
var somethingWeird = false;
if(somethingWeird){
throw new Exception("Something weird just happened!");
} else {
println("We made it through the function.");
}
}
|
Запуская этот скрипт в том виде, в каком он показан (somethingWeird присвоено значение false ), мы получим следующее сообщение:
We made it through the function.
The script is now executing as expected...
|
Однако изменяя значение переменной на
true , мы таким образом ловим исключение. Среда исполнения при запуске такого скрипта выдаст сообщение:
Exception in thread "main" java.lang.Exception: Something weird just happened!
at exceptions.foo(exceptions.fx:10)
at exceptions.javafx$run$(exceptions.fx:3)
|
Для предотвращения сбоя работы скрипта нам необходимо использовать выражения try и catch для функции foo() . Выражение try выполняет некоторый код, а если в процессе выполнения этого кода возникают проблемы, то будет выполняться код, указанный в выражении catch:
Теперь вместо сбоя, программа выводит:
Something weird just happened! (but we caught it)
The script is now executing as expected...
|
Кроме того, существует еще блок finally (технически он не является выражением). Этот блок всегда выполняется для завершения выражения try , вне зависимости от того было ли брошено исключение или нет. Блок finally используется для очистки ресурсов вне зависимости от того, успешно ли было выполнено тело выражения try или было брошено исключение.
Результат работы программы будет таким:
Something weird just happened! (but we caught it)
We are now in the finally expression...
The script is now executing as expected...
|
|