分支结构与条件判断
在实际应用中,我们往往需要用到各种各样的条件判断,判断玩家权限、判断玩家血量等等...
下面我们来学习 Kether 中最常用且最重要的内容:分支结构与条件判断
If & Else 语句
if {action A} then {action B}
if {action A} then {action B} else {action C}
「展开 / 收起详情」💠 If & Else 语句
该语句的作用是判断条件 action A 是否满足,若条件满足,则执行 then 后面的 action B 语句,反之执行 else 后面的 action C 语句
单分支结构
if {action A} then {action B}
单分支结构只涉及一个条件判断。如果该条件为真(true),则执行相关语句,否则跳过
若 action A 参数的返回值为 true 的时候,则会执行 then 后面的 action B 参数语句,反之则跳过
例如判断玩家权限,若拥有某权限则发送一段消息
if perm "security.bypass" then tell "权限认证通过"
当 Permission 语句检测到玩家拥有"security.bypass"权限后,会返回 true,此时 If 语句条件通过,执行 then 后面的语句。
双分支结构
if {action A} then {action B} else {action C}
双分支结构不但判断一个条件,还提供了条件为假时的执行路径。它通常由 if 和 else 共同组成
若 action A 参数的返回值为 true 的时候,则会执行 then 后面的 action B 参数语句,反之则执行 else 后面的 action C 语句
例如判断玩家权限,若拥有某权限则发送一段消息,反之则发送其他消息
if perm "security.bypass" then tell "权限认证通过" else tell "权限认证失败"
多重分支结构
多重分支结构在有多个条件判断时使用,每个条件判断都有自己的语句。
本质上是多个 If & Else 语句的嵌套使用。
if {action A} then {action B}
else if {action C} then {action D}
else {action E}
由于 else 后面的参数类型为 Action,那么它除了填入 Tell 语句之外当然可以嵌套填入另一个 If & Else 语句。以此来组成多重分支结构。
例如判断玩家的会员权限,输出对应的信息
if perm "status.ssvip" then tell "至尊会员"
else if perm "status.svip" then tell "超级会员"
else if perm "status.vip" then tell "会员"
else tell "非会员"
Tips: 在多重分支结构中,需要特别注意前后条件的顺序!
如果上面的例子我反过来写,那么可能会出现一些意料不到的错误:
if perm "status.vip" then tell "会员"
else if perm "status.svip" then tell "超级会员"
else if perm "status.ssvip" then tell "至尊会员"
else tell "非会员"
因为更高级别的会员必定拥有低级会员的所有权限。假如第一个条件判断的是普通会员的权限,那么我作为至尊会员必然拥有该权限,此时条件通过,就会执行第一个 then 后面的内容,即 tell "会员",很显然这并不是正确的结果。
因此在使用多重分支结构的时候,一定要注意条件的判断顺序!
If & Else 语句返回值
不知道你有没有考虑过,If & Else 语句是否有返回值这个问题?来实验一下就知道了:
>/vul eval if perm "security.bypass" then "yes" else "no"
‹ › Result: yes
可以看到,当条件成立时,If & Else 语句的返回值就是 then 后面语句的返回值,反之则是 else 后面语句的返回值
那如果是单分支情况下,条件不满足呢?
>/vul eval if perm "security.bypass" then "yes"
‹ › Result: null
如果不满足的情况下,返回值则为 null,也就是一个空值
总结:单/双分支时,条件满足则返回 then 后面语句的执行结果;单分支条件不满足时,返回值为 null;多重分支同理。
那么了解这个有什么用处吗?当然有!
还记得 Tell 语句的参数是什么类型?Action 类型!
那我们是不是可以把 then 和 else 里面的 Tell 全都提取到最前面来呢?
tell if perm "security.bypass" then "权限认证通过" else "权限认证失败"
这样看起来是不是更简短了!在双分支以及多重分支的时候可以这样简化。单分支的时候就不太建议这样写了,将一个 空值 null 通过 Tell 发送给玩家,聊天栏会收到空白的一行内容,那还不如不发呢。
Check 语句
check {action A} {symbol} {action B}
「展开 / 收起详情」💠 Check 语句
该语句的作用是判断左边的 action A 的返回值与右边 action B 的返回值的关系。
具体判断关系由中间的符号参数 Symbol 决定
判断大小关系
判断大小关系有四种符号:
>
:大于>=
:大于或等于<
:小于<=
:小于或等于
注意:大小关系判断只能用在数字与数字之间,不能用在字符串、数组等其他类型之间!
判断玩家血量是否大于等于某个值
check player health >= 10
判断等价关系
判断相等关系有五种符号:
==
:等于,字面意思上相同!=
:不等于,字面意思上不同=?
:相似等于,将左侧与右侧返回值转化为文本进行相似比对,并且忽略大小写=!
:非推断等于,比较少用=!!
:指左侧与右侧在内存路径上相同,比较少用
例如判断玩家名是否等于某个 ID 或不等于
check player name == "Lanscarlos"
check player name != "Lanscarlos"
例如判断玩家名是否等于某个 ID(忽略大小写)
check player name =? "lanscarlos"
判断包含关系
判断包含关系有两种符号:
in
:左侧 action A 的返回值是否属于右侧 action B 返回值的内容之一has
:左侧 action A 是否含有右侧 action B 内容
例如判断某个文本中是否含有"KFC"字段
check "Crazy KFC Vivo 50" has "KFC"
反过来写也是一样的,符号由 has 换成 in 即可
判断"KFC"字段是否存在于某个文本中
check "KFC" in "Crazy KFC Vivo 50"
判断某个数组内是否含有某个数字
check array [ 1 1 4 5 1 4 ] has 5
check 5 in array [ 1 1 4 5 1 4 ]
Case & When 语句
Case & When 是一种多重分支结构语句,在某些方面会比使用 If & Else 的多重分支更加简洁
假设我们要实现"当玩家血量大于等于 15,10,5,以及其他情况时,分别发送不同的消息"
我们先尝试用 If & Else 的多重分支来实现看看:
tell if check player health >= 15 then "血量充盈"
else if check player health >= 10 then "血量充足"
else if check player health >= 5 then "血量堪忧"
else "血量告急"
是不是看起来特别麻烦?那如果用 Case & When 改写会有多简洁呢?
`tell case player health [
when >= 15 then "血量充盈"
when >= 10 then "血量充足"
when >= 5 then "血量堪忧"
else "血量告急"
]
应该不用我多说了,结果显而易见。
下面我们来学习一下 Case & When 的用法,首先是 Case 语句的整体结构:
case {action A} [
when ...
else {action}
]
case 后面紧跟着的 action A 参数是需要进行判断的值。
在上面的例子中,我们填入的是获取玩家生命值的语句 player health。
中括号内包裹着的是具体的 when 分支,每一条 when 及其后面的语句都是一个分支。
当所有的 when 分支都不满足情况时,则执行 else 后面的语句
Case 的结构大体上是这样,下面我们讲一下 When 的几种写法
关系判断
when {symbol} {action B} then {action C}
when 后面紧跟着的 action B 参数是用来判断与 action A 关系的值
当 case 后面的 action A 与 action B 的关系满足 symbol 符号定义时,则执行 then 后面的 action C 语句
相当于 if check {action A} {symbol} {action B} then {action C}
其中 symbol 符号参考 Check 语句的用法
例如:
tell case player health [
when >= 15 then "血量充盈"
when >= 10 then "血量充足"
when >= 5 then "血量堪忧"
else "血量告急"
]
等价关系判断
when {action B} then {action C}
当省略 when 后面的 {symbol}
符号参数时,则默认进行等价(==
)判断,即 action A == action B
相当于 if check {action A} == {action B} then {action C}
例如,判断血量是否等于某个数值:
tell case player health [
when 20 then "满血状态!"
when 5 then "血量等于 5 HP, 危险!"
else "其他情况"
]
多值等价关系判断
when {action list} then {action C}
这里同样省略了 {symbol}
符号参数,所以是等价判断(==
)
只不过 when 后面的参数类型变成了 Action List,这意味着我们可以传入多个 action 的值,如果 action A 的值,与 action list 中任意一个值相等,那么就执行 then 后面的 action C 语句。
例如判断玩家名字的情况,当玩家名字为 Lanscarlos 或 Spark_nano 时,输出信息"嘻嘻",当玩家名为 bukkitObj 时,输出"哈哈"
tell case player name [
when [ "Lanscarlos" "Spark_nano" ] then "嘻嘻"
when "bukkitObj" then "哈哈"
else "其他情况"
]
Tips: When 的三种不同写法可以同时用到一个 Case 语句里,就像上面这个例子一样。
语句块
前面我们举的例子里,If & Else 语句里的 then 和 else 后面都只填了一个语句,那如果我希望执行多条语句该怎么办呢?这个时候就需要用到语句块了!
if {action A} then {
{action B}
{action C}
}
什么是语句块呢?一条或多条语句用大括号 {...}
括起来,就是语句块。
如上面例子所示,语句 action B 和语句 action C 同时被外层的红色大括号包裹。此时,前后的大括号以及其内部的语句 action B 和语句 action C 就组成了一个语句块。
语句块可以被 Action 类型参数视为语句去读取。换言之,语句块其实可以被粗略看做是一条特殊的语句,语句块在执行时会依次去执行其内部包裹着的子语句,也就是按顺序先执行 action B 然后到 action C。
既然它可被看做是一条语句,那么它的是否具有返回值呢?当然有!你自己试验一下就知道了。
语句块的返回值通常是其内部最后一条子语句的返回值,也就是 action C 语句的返回值。
例如:
if perm "security.bypass" then {
tell player name
tell "权限认证通过"
}
当然,语句块不仅仅可以用在 If & Else 语句里,只要是 Action 类型参数的地方,它都能用!
比如用在 Case & When 里,甚至是 Tell 里面都行!
复合条件判断
在面对一些复杂的条件判断情况时,我们往往需要结合多个条件一起去判断,这个时候就需要借助其他语句了。
Not 语句
not {action}
该语句的作用是将参数的返回值取反,等价于逻辑非。例如:
not perm "security.bypass"
若该玩家拥有"security.bypass"权限,那么 Permission 语句会返回 true 值,而 Not 语句会将该 true 值取反变成 false。
举例:若玩家没有"security.bypass"权限,则发送禁止通过消息
if not perm "security.bypass" then tell "禁止通过!"
Any 语句
any {action list}
该语句的作用是判断 action list 中是否有任意一个语句的返回值为 true。若 action list 中有任意一个语句的返回值为 true,那么整个 Any 语句的返回值为 true,否则返回值为 false。相当于逻辑与。
举例:若玩家拥有"security.admin"或"security.bypass"任意一个权限时,输出信息
if any [ perm "security.admin" perm "security.bypass" ] then tell "权限认证通过"
All 语句
all {action list}
该语句的作用是判断 action list 中是否所有语句的返回值为 true。若 action list 中所有语句的返回值为 true,则All 语句返回值为 true,若任意一个语句返回值为 false,那么 All 语句返回值都将是 false。相当于逻辑与。
举例:若玩家同时拥有"security.admin"和"security.bypass"两个权限时,输出信息
if all [ perm "security.admin" perm "security.bypass" ] then tell "权限认证通过"