diff options
-rw-r--r-- | doc/go_spec.html | 117 |
1 files changed, 103 insertions, 14 deletions
diff --git a/doc/go_spec.html b/doc/go_spec.html index 18c4b84a2..2b2ecbcd3 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -68,7 +68,6 @@ Closed: - added to wish list [x] convert should not be used for composite literals anymore, in fact, convert() should go away - made a todo -[x] type switch or some form of type test needed - duplicate entry [x] provide composite literal notation to address array indices: []int{ 0: x1, 1: x2, ... } and struct field names (both seem easy to do). - under "Missing" list [x] passing a "..." arg to another "..." parameter doesn't wrap the argument again @@ -3121,24 +3120,42 @@ if x := f(); x < y { <p> "Switch" statements provide multi-way execution. -An expression is evaluated and compared to the "case" -expressions inside the "switch" to determine which branch -of the "switch" to execute. -A missing expression is equivalent to <code>true</code>. +An expression or type specifier is compared to the "cases" +inside the "switch" to determine which branch +to execute. +A missing expression or type specifier is equivalent to +the expression <code>true</code>. +There are two forms: expression switches and type switches. </p> -<pre class="grammar"> -SwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { CaseClause } "}" . -CaseClause = SwitchCase ":" StatementList . -SwitchCase = "case" ExpressionList | "default" . -</pre> - <p> -The case expressions, which need not be constants, -are evaluated top-to-bottom; the first one that matches +In an expression switch, the cases contain expressions that are compared +against the value of the switch expression. +In a type switch, the cases contain types that are compared against the +type of a specially annotated switch expression. +</p> + +<pre class="grammar"> +SwitchStat = ExprSwitchStat | TypeSwitchStat . +ExprSwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { CaseClause } "}" . +TypeSwitchStat = "switch" [ [ SimpleStat ] ";" ] TypeSwitchExpression "{" { CaseClause } "}" . +TypeSwitchExpression = identifier ":=" Expression "." "(" "type" ")" . +CaseClause = SwitchCase ":" [ StatementList ] . +SwitchCase = "case" ExpressionList | SwitchAssignment | Type | "default" . +SwitchAssignment = Expression ( "=" | ":=" ) Expression . +SwitchExpression = Expression. +</pre> + +<p> +In an expression switch, +the switch expression is evaluated and +the case expressions, which need not be constants, +are evaluated top-to-bottom; the first one that equals the +switch expression triggers execution of the statements of the associated case; the other cases are skipped. -If no case matches and there is a "default" case, its statements are executed. +If no case matches and there is a "default" case, +its statements are executed. There can be at most one default case and it may appear anywhere in the "switch" statement. </p> @@ -3181,6 +3198,78 @@ case x == 4: f3(); } </pre> +<p> +If the expression in an expression switch is a boolean, the cases +may take a special form that tests a type guard, map index, or +channel operation and stores the value in a variable, which may +be declared using a simple variable declaration. The success +of the case's operation is compared against the value of the boolean. +A switch of the form: +</p> + +<pre> +switch bool_expr { +case x0: + f0(); +case x1 := y1.(T1): + f1(); +case x2 := y2[z2]: + f2(); +case x3 := <-y3: + f3(); +default: + f4(); +} +</pre> + +<p> +is therefore analogous to the "if" statement +</p> + +<pre> +if x0 == bool_expr { + f0(); +} else if x1, ok1 := y1.(T1); ok1 == bool_expr { + f1(); +} else if x2, ok2 := y2[z2]; ok2 == bool_expr { + f2(); +} else if x3, ok3 := <-y3; ok3 == bool_expr { + f3(); +} else { + f4(); +} +</pre> + +<p> +A type switch compares types rather than values. In other respects it has +the same properties as an expression switch and may in fact be rewritten +as an expression switch using type guards. It is introduced by special +notation in the form of a generic type guard using the reserved word +<code>type</code> rather than an actual type. +Given a function <code>f</code> +that returns a value of interface type, +the following two "switch" statements are analogous: +</p> + +<pre> +switch i := f().(type) { +case int: + printInt(i); // i is an int +case float: + printFloat(i); // i is a float +default: + printString("don't know the type"); +} + +switch val := f(); true { +case i := val.(int): + printInt(i); // i is an int +case i := val.(float): + printFloat(i); // i is a float +default: + printString("don't know the type"); +} +</pre> <h3>For statements</h3> |