1
0
mirror of https://github.com/golang/go synced 2024-11-22 00:44:39 -07:00

drop the ,ok switch; keep the straight type switch.

R=rsc,gri
DELTA=97  (26 added, 42 deleted, 29 changed)
OCL=26436
CL=26527
This commit is contained in:
Rob Pike 2009-03-18 19:23:59 -07:00
parent f7772627ad
commit 70c1a106e6

View File

@ -3123,28 +3123,14 @@ if x := f(); x < y {
An expression or type specifier is compared to the "cases" An expression or type specifier is compared to the "cases"
inside the "switch" to determine which branch inside the "switch" to determine which branch
to execute. 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. There are two forms: expression switches and type switches.
</p>
<p>
In an expression switch, the cases contain expressions that are compared In an expression switch, the cases contain expressions that are compared
against the value of the switch expression. against the value of the switch expression.
In a type switch, the cases contain types that are compared against the In a type switch, the cases contain types that are compared against the
type of a specially annotated switch expression. type of a specially annotated switch expression.
</p> </p>
<pre class="grammar"> <h4>Expression switches</h4>
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> <p>
In an expression switch, In an expression switch,
@ -3158,7 +3144,17 @@ If no case matches and there is a "default" case,
its statements are executed. its statements are executed.
There can be at most one default case and it may appear anywhere in the There can be at most one default case and it may appear anywhere in the
"switch" statement. "switch" statement.
A missing expression is equivalent to
the expression <code>true</code>.
</p> </p>
<pre class="grammar">
SwitchStat = ExprSwitchStat | TypeSwitchStat .
ExprSwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
ExprCaseClause = ExprSwitchCase ":" [ StatementList ] .
ExprSwitchCase = "case" ExpressionList | "default" .
</pre>
<p> <p>
In a case or default clause, In a case or default clause,
the last statement only may be a "fallthrough" statement the last statement only may be a "fallthrough" statement
@ -3168,7 +3164,7 @@ the first statement of the next clause.
Otherwise control flows to the end of the "switch" statement. Otherwise control flows to the end of the "switch" statement.
</p> </p>
<p> <p>
Each case clause effectively acts as a block for scoping purposes Each case clause acts as a block for scoping purposes
(§Declarations and scope rules). (§Declarations and scope rules).
</p> </p>
<p> <p>
@ -3198,57 +3194,29 @@ case x == 4: f3();
} }
</pre> </pre>
<h4>Type switches</h4>
<p> <p>
If the expression in an expression switch is a boolean, the cases A type switch compares types rather than values. It is otherwise similar
may take a special form that tests a type guard, map index, or to an expression switch. It is introduced by special
channel operation and stores the value in a variable, which may notation in the form of a simple declaration whose right hand side
be declared using a simple variable declaration. The success has the form of a type guard (§Type guards)
of the case's operation is compared against the value of the boolean. using the reserved word <code>type</code> rather than an actual type.
A switch of the form: Cases then match literal types against the dynamic type of the expression
in the type guard.
</p> </p>
<pre> <pre class="grammar">
switch bool_expr { TypeSwitchStat = "switch" [ [ SimpleStat ] ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
case x0: TypeSwitchGuard = identifier ":=" Expression "." "(" "type" ")" .
f0(); TypeCaseClause = TypeSwitchCase ":" [ StatementList ] .
case x1 := y1.(T1): TypeSwitchCase = "case" type | "default" .
f1();
case x2 := y2[z2]:
f2();
case x3 := <-y3:
f3();
default:
f4();
}
</pre> </pre>
<p> <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> Given a function <code>f</code>
that returns a value of interface type, that returns a value of interface type,
the following two "switch" statements are analogous: the following type switch:
</p> </p>
<pre> <pre>
@ -3257,20 +3225,36 @@ case int:
printInt(i); // i is an int printInt(i); // i is an int
case float: case float:
printFloat(i); // i is a float printFloat(i); // i is a float
default: case func(int) float:
printString("don't know the type"); printFunction(i); // i is a function
}
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: default:
printString("don't know the type"); printString("don't know the type");
} }
</pre> </pre>
<p>
could be rewritten:
</p>
<pre>
v := f();
if i, is_int := v.(int); is_int {
printInt(i); // i is an int
} else if i, is_float := v.(float); is_float {
printFloat(i); // i is a float
} else if i, is_func := v.(func(int) float); is_func {
printFunction(i); // i is a function
} else {
printString("don't know the type");
}
</pre>
<p>
In a type switch, the guard is mandatory,
there can be only one type per "case", and
the "fallthrough" statement is not allowed.
</p>
<h3>For statements</h3> <h3>For statements</h3>
<p> <p>