使用变量和表达式
简介
与 Python 类似,Colang 支持以下基本数据类型:string、int、float、bool、list、set、dict,以及 Colang 特定的 event、action 和 flow 引用。我们已经了解了如何使用 ... as $ref
符号将 event、action 和 flow 引用分配给变量。这里 $ref
也只是一个变量。为了在 flow 名称中启用空格字符,Colang 变量必须始终以 $
字符开头,并且自身不能包含空格字符。
重要提示
变量命名约定
必须以字母字符开头
可以包含字母数字字符,包括
_
区分大小写
Regular expression: \$[^\W\d]\w*
Colang 中的变量行为与 Python 中完全相同。因此,对于像 list 这样的可变数据类型,新的变量赋值不会复制,而只是被新变量引用。
flow main
$value = "Hi"
$value_copy = $value # Copy of the value
await UtteranceBotAction(script=$value_copy)
match AnEvent()
请注意,Colang 引用也是可变的,因此指向相同的底层对象
flow main
match UtteranceUserAction.Finished() as $ref
$ref_copy = $ref # Both references are pointing to same event object
await UtteranceBotAction(script=$ref_copy.final_transcript)
match AnEvent()
目前,不支持创建其他变量的引用。引用只能指向 event、action 或 flow 对象,并且在 send
、match
、start
或 await
语句中使用 as
关键字创建。
重要提示
对变量的赋值将始终在内存中创建值的副本
event、action 或 flow 引用的副本仍然指向相同的对象
Flow 参数按值传递
以下是一些变量赋值示例
$string_value = "Hi"
$integer_value = 42
$float_value = 3.14159
$list_of_strings = ["one", "two", "three"]
$list_of_integers = [1, 2, 3, 4]
$set_of_floats = {0.1, 0.2, 0.3}
$dictionary = {"value_a":1, "value_b": 2}
表达式求值
Colang 支持对简单和复合数据类型求值常见的 Python 表达式(请参阅 Simple Eval)
# Arithmetic expressions
21 + 21
21 + 19 / 7 + (8 % 3) ** 9
# Supported operators
+, -, *, / # standard arithmetic operators
** # to the power of: 2 ** 10 -> 1024
% # modulus
==, <, >, <=, >= # comparison operators
in # is something contained within something else
not in # is something not contained within something else
>>, <<, ^, |, &, ~ # Bitwise operators
# Conditional expressions
"equal" if x == y else "not equal"
"a" if 1 == 2 else "b" if 2 == 3 else "c"
# Compound data types
list_variable[0] # Access item by index
dict_variable[key] # Access item by key
object.attribute # Access object attribute
# Supported custom functions
len(obj: Any) -> int # Return number of items of a compound variable
regex(pattern: str) -> Pattern # Creates a regex pattern that can be compared to
search(pattern: str, string: str) -> bool # Check for regex pattern in string
findall(pattern: str, string: str) -> List[str] # Return all matches of regex pattern with string
uid() -> str # Create new universal unique identifier
int(string: str) -> int # Convert the number in the string to an int
float(string: str) -> float # Convert the number in the string to a float
str(x: Any) -> str # Convert x to a string
pretty_str(x: Any) -> str # Convert x to a formatted string
int(x: Any) -> int # Convert x to a int
float(x: Any) -> float # Convert x to a float
escape(string: str) -> str # Escape a string and expressions inside the string
is_bool(x: Any) -> bool # Check if x is a bool
is_int(x: Any) -> bool # Check if x is an int
is_float(x: Any) -> bool # Check if x is a float
is_str(x: Any) -> bool # Check if x is a str
is_regex(x: Any) -> bool # Check if x is a regex pattern
rand() -> float # Return a random float between 0 and 1
randint(x: int) -> int # Return a random int below x
flows_info() -> dict # Returns a dictionary that contains more information about the current flow
以下是如何在 Colang 中使用表达式的方法
# Expression in an assignment
$dict = {"value": 2 + 3}
# Expression as standalone statement
($dict.update({"value": 4}))
# Expression as a flow parameter
bot count to ($dict["value"])
您可以看到表达式如何在不同的上下文中使用,并且如果用作独立语句或flow 参数,则需要用括号括起来。
Flow 变量访问
默认情况下,在 flow 中定义的变量具有局部作用域,并且无法从 flow 外部访问。启用访问的一种方法是在 flow 定义中使用 定义 Flow 中所示的符号将它们声明为 flow 属性
flow main
await user said something as $ref
await UtteranceBotAction(script=$ref.transcript)
match AnEvent()
flow user said something -> $transcript
match UtteranceUserAction.Finished() as $event_ref
$transcript = $event_ref.final_transcript
通过这种方式,我们可以访问用户转录,并使用它通过 bot 发言动作重复它。
在 flow 之间使用变量共享信息的另一种方法是使用关键字 global
使其成为全局变量。
flow main
global $transcript
await bot said something
await UtteranceBotAction(script=$transcript)
match AnEvent()
flow bot said something
global $transcript
match UtteranceUserAction.Finished() as $event_ref
$transcript = $event_ref.final_transcript
正如您从示例中看到的,我们需要在每个 flow 中定义变量 $transcript
是全局的,以便访问全局实例。否则,它将是一个隐藏全局实例的局部变量。但是,请三思而后行是否使用全局变量,因为它可能表明 Colang 设计不是最优的。
字符串中的表达式
与 Python 的格式化字符串文字一样,我们可以使用花括号来计算字符串内的表达式 "{$variable}"
flow main
$user_name = "John"
await UtteranceBotAction(script="Hi {$user_name}!")
match AnEvent()
如果需要在文字文本中包含花括号字符,可以通过加倍来转义它:{{
和 }}
。
内置 Flow 变量
重要提示
这是正在进行的工作,一些内置变量将来可能会更改或删除。
目前,有一些变量名称不能在 flow 中用作自定义变量名称。它们包含 flow 实例特定信息
$system: dict # System specific data like e.g. the current bot configuration `$system.config`
$uid: str # The unique id of the flow instance
$flow_id: str # The name of the current flow
$loop_id: Optional[str] # The interaction loop id of the current flow
$parent_uid: Optional[str] # The unique id of the parent flow instance
$child_flow_uids: List[str] # All unique ids of the child flow instances
$context: dict # The current variable context that contains all user defined variables in the flow
$priority: float # Current priority of the flow
$arguments: dict # All arguments of the flow
$flow_instance_uid: str # Flow instance specific uid
$source_flow_instance_uid: str # The parent flow uid of the flow
$activate: bool # True if the flow was activated and will therefore restart immediately when finished
$new_instance_started: bool # True if new instance was started of an activated flow
# Other internal flow members that cannot be used:
$hierarchy_position, $heads, $scopes, $head_fork_uids, $action_uids, $global_variables,
$status_updated, $source_head_uid
接下来,我们将学习如何使用 Flow 控制 来创建分支或循环交互模式。