close #18092 document elif in case statements (#18105)

* close #18092 [skip ci] document elif in case statements

* fixup

* clarify spec; mention special rule for string in case statements

* address comments
This commit is contained in:
Timothee Cour 2021-05-31 13:14:50 -07:00 • committed by GitHub
commit 60cbdbf37a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2981,11 +2981,13 @@ Example:
.. code-block:: nim .. code-block:: nim
case readline(stdin) let line = readline(stdin)
case line
of "delete-everything", "restart-computer": of "delete-everything", "restart-computer":
echo "permission denied" echo "permission denied"
of "go-for-a-walk": echo "please yourself" of "go-for-a-walk": echo "please yourself"
else: echo "unknown command" elif line.len == 0: echo "empty" # optional, must come after `of` branches
else: echo "unknown command" # ditto
# indentation of the branches is also allowed; and so is an optional colon # indentation of the branches is also allowed; and so is an optional colon
# after the selecting expression: # after the selecting expression:
@ -2996,19 +2998,23 @@ Example:
else: echo "unknown command" else: echo "unknown command"
The `case` statement is similar to the if statement, but it represents The `case` statement is similar to the `if` statement, but it represents
a multi-branch selection. The expression after the keyword `case` is a multi-branch selection. The expression after the keyword `case` is
evaluated and if its value is in a *slicelist* the corresponding statements evaluated and if its value is in a *slicelist* the corresponding statements
(after the `of` keyword) are executed. If the value is not in any (after the `of` keyword) are executed. If the value is not in any
given *slicelist* the `else` part is executed. If there is no `else` given *slicelist*, trailing `elif` and `else` parts are executed using same
part and not all possible values that `expr` can hold occur in a semantics as for `if` statement, and `elif` is handled just like `else: if`.
*slicelist*, a static error occurs. This holds only for expressions of If there are no `else` or `elif` parts and not
ordinal types. "All possible values" of `expr` are determined by `expr`'s all possible values that `expr` can hold occur in a *slicelist*, a static error occurs.
type. To suppress the static error an `else` part with an This holds only for expressions of ordinal types.
empty `discard` statement should be used. "All possible values" of `expr` are determined by `expr`'s type.
To suppress the static error an `else: discard` should be used.
For non-ordinal types, it is not possible to list every possible value and so For non-ordinal types, it is not possible to list every possible value and so
these always require an `else` part. these always require an `else` part.
An exception to this rule is for the `string` type, which currently doesn't
require a trailing `else` or `elif` branch; it's unspecified whether this will
keep working in future versions.
Because case statements are checked for exhaustiveness during semantic analysis, Because case statements are checked for exhaustiveness during semantic analysis,
the value in every `of` branch must be a constant expression. the value in every `of` branch must be a constant expression.
@ -3054,15 +3060,15 @@ won't work:
var foo = Foo(x: @[]) var foo = Foo(x: @[])
foo.get_x().add("asd") foo.get_x().add("asd")
This can be fixed by explicitly using `return`: This can be fixed by explicitly using `result` or `return`:
.. code-block:: nim .. code-block:: nim
proc get_x(x: Foo): var seq[string] = proc get_x(x: Foo): var seq[string] =
case true case true
of true: of true:
return x.x result = x.x
else: else:
return x.x result = x.x
When statement When statement