Case 语句
Example:
let line = readline(stdin)
case line
of "delete-everything", "restart-computer":
echo "permission denied"
of "go-for-a-walk": echo "please yourself"
elif line.len == 0: echo "empty" # optional, must come after `of` branches
else: echo "unknown command" # ditto
# 允许分支缩进;
# 在选择表达式之后的冒号是可选:
case readline(stdin):
of "delete-everything", "restart-computer":
echo "permission denied"
of "go-for-a-walk": echo "please yourself"
else: echo "unknown command"
case 语句类似于 if 语句, 它表示一种多分支选择。 关键字 case 后面的表达式进行求值, 如果其值在 slicelist 列表中, 则执行 of 关键字之后相应语句。 如果其值不在已给定的 slicelist 中, 那么所执行的 elif 、 else 语句部分与 if 语句相同, elif 的处理就像 else: if 。 如果没有 else 或 elif 部分,并且 expr 未能持有所有可能的值,则在 slicelist 会发生静态错误。 但这仅适用于序数类型的表达式。 expr 的 “所有可能的值” 由 expr 的类型决定,为了防止静态错误应该使用 else: discard。
在 case 语句中,只允许使用序数类型、浮点数、字符串和 cstring 作为值。
对于非序数类型, 不可能列出每个可能的值,所以总是需要 else 部分。 此规则 string 类型是例外,目前,它不需要在后面添加 else 或 elif 分支, 但在未来版本中不确定。
因为在语义分析期间检查 case 语句的穷尽性,所以每个 of 分支中的值必须是常量表达式。 此限制可以让编译器生成更高性能的代码。
一种特殊的语义扩展是, case 语句 of 分支中的表达式可以为集合或数组构造器, 然后将集合或数组扩展为其元素的列表:
const
SymChars: set[char] = {'a'..'z', 'A'..'Z', '\x80'..'\xFF'}
proc classify(s: string) =
case s[0]
of SymChars, '_': echo "an identifier"
of '0'..'9': echo "a number"
else: echo "other"
# 等价于:
proc classify(s: string) =
case s[0]
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_': echo "an identifier"
of '0'..'9': echo "a number"
else: echo "other"
case 语句不会产生左值, 所以下面的示例无效:
type
Foo = ref object
x: seq[string]
proc get_x(x: Foo): var seq[string] =
# 无效
case true
of true:
x.x
else:
x.x
var foo = Foo(x: @[])
foo.get_x().add("asd")
这可以通过显式使用 result 或 return 来修复:
proc get_x(x: Foo): var seq[string] =
case true
of true:
result = x.x
else:
result = x.x
当前内容版权归 vectorworkshopbaoerjie 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 vectorworkshopbaoerjie .