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:
parent
f7772627ad
commit
70c1a106e6
120
doc/go_spec.html
120
doc/go_spec.html
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user