From: Robert Griesemer x.(T)
is called a type assertion.
More precisely, if T
is not an interface type, x.(T)
asserts
that the dynamic type of x
is identical
to the type T
.
+In this case, T
must implement the (interface) type of x
;
+otherwise the type assertion is invalid since it is not possible for x
+to store a value of type T
.
If T
is an interface type, x.(T)
asserts that the dynamic type
-of x
implements the interface T
(§Interface types).
+of x
implements the interface T
.
If the type assertion holds, the value of the expression is the value
@@ -2679,8 +2682,19 @@ In other words, even though the dynamic type of x
is known only at run time, the type of x.(T)
is
known to be T
in a correct program.
+var x interface{} = 7 // x has dynamic type int and value 7 +i := x.(int) // i has type int and value 7 + +type I interface { m() } +var y I +s := y.(string) // illegal: string does not implement I (missing method m) +r := y.(io.Reader) // r has type io.Reader and y must implement both I and io.Reader ++
-If a type assertion is used in an assignment or initialization of the form +If a type assertion is used in an assignment or initialization of the form
@@ -2696,7 +2710,7 @@ otherwise, the expression returns(Z, false)
whereZ
is the zero value for typeT
. No run-time panic occurs in this case. The type assertion in this construct thus acts like a function call -returning a value and a boolean indicating success. (§Assignments) +returning a value and a boolean indicating success. @@ -4159,9 +4173,20 @@ case x == 4: f3() A type switch compares types rather than values. It is otherwise similar to an expression switch. It is marked by a special switch expression that has the form of a type assertion -using the reserved wordtype
rather than an actual type. -Cases then match literal types against the dynamic type of the expression -in the type assertion. +using the reserved wordtype
rather than an actual type: + + ++switch x.(type) { +// cases +} ++ ++Cases then match actual types
T
against the dynamic type of the +expressionx
. As with type assertions,x
must be of +interface type, and each non-interface type +T
listed in a case must implement the type ofx
.@@ -4197,17 +4222,17 @@ the following type switch:switch i := x.(type) { case nil: - printString("x is nil") + printString("x is nil") // type of i is type of x (interface{}) case int: - printInt(i) // i is an int + printInt(i) // type of i is int case float64: - printFloat64(i) // i is a float64 + printFloat64(i) // type of i is float64 case func(int) float64: - printFunction(i) // i is a function + printFunction(i) // type of i is func(int) float64 case bool, string: - printString("type is bool or string") // i is an interface{} + printString("type is bool or string") // type of i is type of x (interface{}) default: - printString("don't know the type") + printString("don't know the type") // type of i is type of x (interface{}) }@@ -4218,22 +4243,23 @@ could be rewritten:v := x // x is evaluated exactly once if v == nil { + i := v // type of i is type of x (interface{}) printString("x is nil") } else if i, isInt := v.(int); isInt { - printInt(i) // i is an int + printInt(i) // type of i is int } else if i, isFloat64 := v.(float64); isFloat64 { - printFloat64(i) // i is a float64 + printFloat64(i) // type of i is float64 } else if i, isFunc := v.(func(int) float64); isFunc { - printFunction(i) // i is a function + printFunction(i) // type of i is func(int) float64 } else { - i1, isBool := v.(bool) - i2, isString := v.(string) + _, isBool := v.(bool) + _, isString := v.(string) if isBool || isString { - i := v - printString("type is bool or string") // i is an interface{} + i := v // type of i is type of x (interface{}) + printString("type is bool or string") } else { - i := v - printString("don't know the type") // i is an interface{} + i := v // type of i is type of x (interface{}) + printString("don't know the type") } }@@ -4501,7 +4527,8 @@ If any of the resulting operations can proceed, one of those is chosen and the corresponding communication and statements are evaluated. Otherwise, if there is a default case, that executes; if there is no default case, the statement blocks until one of the communications can -complete. +complete. There can be at most one default case and it may appear anywhere in the +"select" statement. If there are no cases with non-nil
channels, the statement blocks forever. Even if the statement blocks,