Не стоит бояться ошибок в виде отсутствия результата или неоднозначности — их можно эффективно использовать при программировании. Обрабатывая отсутствие результата, можно научиться отладке, узнать ограничения программы или быстро понять, чего не стоит делать.
Отсутствие результата или неоднозначность — это нормально
В языке Verse ошибка в виде отсутствия результата или неоднозначности имеет особый смысл. Она не всегда означает, что что-то не работает. Это способ управлять выполнением программы.
Помните, в уроке 4 вы узнали, что в коде можно задать вопрос да / нет?
var Tired: logic = false
var WhatToWatch: string = “ничего”
if (Tired?):
set WhatToWatch = “свои веки”
else:
set WhatToWatch = “мультфильмы”
Print(“Лучше посмотрите: {WhatToWatch}”)
# Лучше посмотрите мультфильмы
Код, задающий вопрос, написан в виде выражения с возможным отсутствием результата. В примере выше таким выражением является Tired?.
Выражения с возможным отсутствием результата используются для предотвращения ошибок, способных помешать выполнению программы. К примеру, все мы знаем, что делить на ноль нельзя. Если вы попытаетесь сделать это в своём коде, программа может завершиться аварийно! Однако следующий код Verse не создаст проблем.
if (5/0):
Print("Ой!")
else:
Print("Это недопустимая операция!")
Во избежание подобных ошибок выражения с возможным отсутствием результата в коде Verse необходимо использовать в контексте с возможным отсутствием результата. Контексты с возможным отсутствием результата позволяют безопасно обрабатывать отсутствие результата (неоднозначность) выражений. В примере выше таким выражением является 5/0, а if()— это контекст с возможным отсутствием результата. Далее приведено подробное описание обеих этих концепций Verse.
Выражения с возможным отсутствием результата
В Verse выражения с возможным отсутствием результата можно записывать по-разному. Если выражение задаёт вопрос с вариантами ответа «да / нет», вероятно, это как раз выражение с возможным отсутствием результата.
Вот несколько типов вопросов, которые могут задаваться в подобных выражениях:
- Из этих двух переменных одна больше / меньше другой или они равны?
- Для этой переменной задано значение
true? - Для этой переменной задано значение?
- Это выражение приводит к ошибке?
Если ответом на любой из этих вопросов будет да, то выражение выполнится успешно. Если ответом будет нет, то выражение не даст результата. Вы сами можете написать код, выполняемый при успешном выполнении выражения или при отсутствии результата.
Выражения сравнения
Выражения сравнения, в которых используются такие операторы сравнения, как < (меньше, чем), ` > (больше, чем) или <> (не равны), являются выражениями с возможным отсутствием результата. В следующем примере 5 < 4` является таким выражением с возможным отсутствием результата:
if (5 < 4):
Print(“Этот текст не будет выводиться.”)
Выражение 5 < 4 — это вопрос “5 меньше, чем 4?”. Ответом будет нет, выражение не даст результата, и блок кода (с отступом под выражением if) не выполнится.
Рассмотрим следующий пример, где выражением с возможным отсутствием результата является MousetrapsSet <> MiceCaught. Оно представляет собой вопрос “Значения MousetrapsSet и MiceCaught не равны?”.
MousetrapsSet := 3
MiceCaught := 0
if (MousetrapsSet<>MiceCaught):
Print(“Нужно больше сыра!”)
На этот раз ответ на вопрос да, потому что для MousetrapsSet задано значение 3, а для MiceCaught значение 0, поэтому выражение выполнится успешно и также выполнится последующий блок кода.
Выражения принятия решения
Выражения принятия решения, в которых используются операторы and, or и not, являются выражениями с возможным отсутствием результата. В следующем примере MousetrapsForSale > 0 and Coins >= MousetrapCost — это выражение с возможным отсутствием результата, которое выполнится успешно, потому что для MousetrapsForSale задано значение 5 (что больше 0), для Coins — 30, а для MousetrapCost — 20 (30 больше, чем 20). Оба выражения сами по себе выполнятся успешно, поэтому выражение в целом тоже выполнится успешно.
MousetrapsForSale := 5
MousetrapCost := 20
Coins := 30
if (MousetrapsForSale > 0 and Coins >= MousetrapCost):
Print(“Вы можете купить мышеловки.”)
Выражения запроса
Выражения запроса также являются выражениями с возможным отсутствием результата. В них используется оператор ? для проверки определённых условий, к примеру задано ли для logic значение true. В следующем примере MousetrapStoreOpen? является выражением с возможным отсутствием результата, которое не выдаёт результат, поскольку MousetrapStoreOpen имеет значение false.
var MousetrapStoreOpen : logic = false
if (MousetrapStoreOpen?):
Print(“Зайдите!”)
Контексты с возможным отсутствием результата
В коде выше выражение if — это контекст с возможным отсутствием результата для выражений с возможным отсутствием результата, записанных в круглых скобках (). Такие контексты допускают отсутствие результата выражений с возможным отсутствием результата, поскольку они определяют, что произойдёт в случае отсутствия результата.
Из предыдущего урока вы знаете, что если выражение в if не даёт результата, код в блоке if не выполняется.
Поскольку if создаёт контекст, допускающий отсутствие результата, вы можете поместить в блок кода этого выражения любое количество выражений с возможным отсутствием результата. Если какое-либо из этих выражений не даст результата, выражения в блоке кода, стоящие перед ним, будут отменены, или откачены.
Существует и другой способ записи выражений if без (). Он подойдёт, если нужно записать много выражений. Пример:
MousetrapsSet:int = 5
var MiceCaught:int = 0
var BreakTime:logic = false
if:
MousetrapsSet > 0
set BreakTime = true
MiceCaught > 0
if (BreakTime?):
Print("Отдохните!")
else:
Print("Поймайте несколько мышей!")
Не все выражения в контексте, допускающем отсутствие результата, должны быть выражениями с возможным отсутствием результата, но хотя бы одно должно быть таковым. В примере выше выражение set BreakTime = true не является выражением с возможным отсутствием результата, в отличие от других выражений.
В коде выше каждое выражение с отступом под if находится внутри контекста с возможным отсутствием результата. Все три выражения выполнятся.
MousetrapsSet > 0выполнится успешно.- Выражение
set BreakTime = trueтакже выполнится. Оно не является выражением с возможным отсутствием результата, поэтому проверка на отсутствие результата не проводится. - А вот
MiceCaught > 0не даст результата.
Поскольку результата не будет, каждое выражение в блоке кода if будет откачено, в том числе set BreakTime = true. Все будет так, как будто этот код вообще не выполнялся. Если вы запустите этот код, то увидите, что будет выведена фраза “Поймайте несколько мышей!”.
При программировании вы заметите, что значительная часть кода выполняется только при условии успешного выполнения другого кода. Это ещё одна причина, по которой контексты с возможным отсутствием результата так полезны. Если сгруппировать зависимый код в контексты с возможным отсутствием результата, можно избежать распространённых ошибок при выполнении программы. Помните код в уроке 4, который вы использовали для принятия решения о том, идти ли в кино? Поскольку вы решили пойти в кино с друзьями, вам нужно раздобыть для них билеты, напитки и закуски!
var Drinks:int = 4
var Snacks:int = 4
var Tickets:int = 3
var FriendsAvailable:int = 4
if:
Drinks >= FriendsAvailable
set Drinks -= FriendsAvailable
Snacks >= FriendsAvailable
set Snacks -= FriendsAvailable
Tickets >= FriendsAvailable
set Tickets -= FriendsAvailable
Print("Осталось напитков: { Drinks }")
Print("Осталось закусок: { Snacks }")
Print("Осталось билетов: { Tickets }")
Оператор -= объединяет в себе операторы вычитания и присваивания. В примере выше выражение set Tickets -= FriendsAvailable эквивалентно выражению set Tickets = Tickets - FriendsAvailable. Аналогичные операторы существуют для сложения (+=), умножения (*=) и деления (/=).
У вас достаточно напитков и закусок для друзей, но недостаточно билетов. Это значит, что вы с друзьями не сможете пойти в кино. Вы можете написать код для обработки этой ситуации, но вы ведь не захотите выбрасывать напитки и закуски.
К счастью, при выполнении кода выражение Tickets >= FriendsAvailable не выдаст результат и весь код в блоке if будет откачен. Это значит, что обе переменные Drinks и Snacks вернутся к значению 4.
Выводы
- В Verse отсутствие результата — это способ управлять выполнением программы.
- Выражения с возможным отсутствием результата могут выполняться успешно или не выдавать результат, и они должны записываться в контексте, допускающем отсутствие результата. Вы можете написать собственный код, выполняемый при успешном выполнении или при отсутствии результата.
- Контексты с возможным отсутствием результата обеспечивают безопасную обработку отсутствия результата (неоднозначности) при выполнении выражений. Любое отсутствие результата в таком контексте приводит к тому, что весь код в этом контексте откатывается, как будто он никогда не выполнялся.