流程控制#
流程控制是所有编程语言中的基本工具,Colang 也支持这一点。它可以在单个流程中实现交互模式的分支和重复。
条件分支 (if/elif/else
)#
重要
条件分支的语法定义
if <condition1>
<interaction pattern sequence 1>
[elif <condition2>
<interaction pattern sequence 2>]
.
.
.
[else
<interaction pattern else sequence>]
条件分支是一个众所周知的概念,其工作原理与 Python 完全相同
flow main
$number_of_users = 1
if $number_of_users == 0
await user became present
elif $number_of_users > 1
bot say "I am sorry, I can only interact with a single user!"
else
bot say "Welcome! Nice to meet you!"
match RestartEvent()
在此示例中,bot 的反应取决于变量 $number_of_users
的状态,该变量包含可用用户的数量。
事件分支 (when/or when/else
)#
事件分支是基于 Colang 的新概念,它允许基于预期事件进行分支。
重要
基于事件的分支的语法定义
when <MixedGroup1>
<interaction pattern sequence 1>
[or when <MixedGroup2>
<interaction pattern sequence 2>]
.
.
.
[else
<interaction pattern else sequence>]
<MixedGroup> 表示流程、操作和事件的混合分组
when/or when
语句中的所有操作和流程将并发启动如果既没有使用
or when
语句也没有使用else
语句,则when
结构可以仅替换为await
或match
语句
通过并发模式匹配机制,我们已经看到了根据用户输入设计分支交互模式的一种方法
flow main
bot say "How are you?"
bot react to user feeling good or bot react to user feeling bad
flow bot react to user feeling good
user said "Good" or user said "Great"
bot say "Great"
flow bot react to user feeling bad
user said "Bad" or user said "Terrible"
bot say "Sorry to hear"
根据用户的回答,我们将得到不同的 bot 反应。尽管这种并发流程机制非常强大,但在某些情况下,借助 when
结构将所有内容放在单个流程中会更好
flow main
bot say "How are you?"
bot react to user wellbeing
flow bot react to user wellbeing
when user said "Good" or user said "Great"
bot say "Great"
or when user said "Bad" or user said "Terrible"
bot say "Sorry to hear"
通过添加更多的 or when
语句,可以轻松扩展案例数量。else
语句仅在所有 when/or when
语句都失败时才会触发。
从定义中可以看出,when/or when
语句支持包含事件、操作和流程的混合组。对于事件,这类似于 match
语句,而对于操作和流程,其行为类似于 await
语句。因此,操作和流程将启动,然后与它们的 Finished
事件进行匹配。请注意,所有流程和操作将在不同的 when/or when
语句中并发启动,并在第一个案例成功时立即停止。
重要
所有 when/or when
语句中启动的所有流程和操作将在任何一个案例成功时立即停止。
我们还可以使用此结构轻松地为一个完成或失败的流程创建分支
flow main
start pattern a
when pattern b
bot say "Pattern b has finished"
else
bot say "Pattern b has failed"
flow pattern a
user said "Hello"
bot say "Hello"
flow pattern b
user said something
bot say "Hi"
由于事件生成冲突解析,'pattern b' 对于用户输入“Hello”将失败,但对于用户输入“Hi”将成功完成
> Hello
Hello
Pattern b has failed
> Hi
Hi
Pattern b has finished
当与以操作开头的类似操作的流程一起使用时,这被认为是“糟糕的设计”
flow bot greet then comment
when bot say "Hi there!"
bot say "I am done talking first"
or when bot gesture "Wave with one hand"
bot say "I am done gesturing first"
flow bot say $text
await UtteranceBotAction(script=$text)
flow bot gesture $gesture
await GestureBotAction(gesture=$gesture)
此示例将无法正常工作,因为由于 UtteranceBotAction
和 GestureBotAction
之间的操作冲突,两个操作中只有一个会启动。请注意,如果遵循适当的流程命名约定,可以轻松检测到此类情况,因为 when bot say "Hi there!"
在语法上不正确。上面的示例需要按如下方式实现
flow bot greet then comment
start bot say "Hi there!" as $action_1_ref
and bot gesture "Wave with one hand" as $action_2_ref
when $action_1_ref.Finished()
bot say "I am done talking first"
or when $action_2_ref.Finished()
bot say "I am done gesturing first"
重要
when/or when/else
分支只能与类似意图的流程一起使用。
循环 (while
)#
重要
循环的语法定义
while <condition>
<interaction pattern sequence>
在此示例中,bot 将从一数到十
flow main
bot count to 10
flow bot count to $number
$current_number = 1
while $current_number < $number
bot say "{$current_number}"
$current_number = $current_number + 1
为了提早中止循环或跳过当前循环迭代的其余部分,可以使用关键字 break
和 continue
flow bot count to $number
$current_number = 0 # Initialized it with 0
while True # Endless loop
bot say "{$current_number}"
$current_number = $current_number + 1
if $current_number == 0
continue # Skip the number 0
if $current_number > $number
break # Break out of loop when target number was reached
结束或中止流程 (return/abort
)#
可以在流程的任何点使用关键字 return
和 abort
来结束或失败流程
flow main
user greeted then expressed feeling unwell
flow user greeted then expressed feeling unwell
match user greeted
when user expressed feeling unwell
return
or when user said something
abort
# We never reach this, except if both cases fail
此外,return
接受一个可选值,以便您可以像普通函数一样使用流程
flow main
$result = await multiply 3 4
bot say "{$result}"
flow multiply $number_1 $number_2
return $number_1 * $number_2
如果未提供返回值,则默认传递 None
。
注意
将流程的返回值赋给变量时,流程名称前的 await
不再可选。
无操作 (pass
)#
有时,拥有一个无操作关键字 pass
很有用,例如作为占位符使语法有效
flow main
user greeted then expressed feeling unwell
flow user greeted then expressed feeling unwell
match user greeted
when user expressed feeling unwell
pass # Just continue with the flow
or when user said something
abort
# The flow will successfully finish here