流程控制
流程控制是所有编程语言中的一个基本工具,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()
在此示例中,机器人的反应取决于变量 $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> 代表流程、actions 和事件的混合分组
when/or when
语句中的所有 actions 和 flows 将并发启动如果既没有使用
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"
根据用户的回答,我们将得到不同的机器人反应。虽然这种并发流程机制非常强大,但有时最好借助 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
语句支持可以包含事件、actions 和 flows 的混合组。对于事件,这就像 match
语句,而对于 actions 和 flows,它的行为类似于 await
语句。因此,actions 和 flows 将启动,然后与其 Finished
事件匹配。请注意,所有 flows 和 actions 将在不同的 when/or when
语句中并发启动,并在第一个案例成功后立即停止。
重要提示
一旦其中一个案例成功,所有 when/or when
语句中启动的所有 flows 和 actions 都将停止。
我们还可以使用此结构轻松地为流程创建分支,该流程可以完成或失败
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"
由于事件生成冲突解决,对于用户输入 “Hello”,‘pattern b’ 将失败,但对于用户输入 “Hi” 将成功完成
> Hello
Hello
Pattern b has failed
> Hi
Hi
Pattern b has finished
当与以 action 开头的类似 action 的 flows 一起使用时,这被认为是“糟糕的设计”
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
之间的 action 冲突,只会启动两个 action 中的一个。请注意,当遵循正确的 flow 命名约定 时,可以轻松检测到此类情况,因为 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
分支应仅与类似 intent 的 flows 一起使用。
循环 (while
)
重要提示
循环的语法定义
while <condition>
<interaction pattern sequence>
在此示例中,机器人将从一数到十
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