|  | package main | 
|  |  | 
|  | // Tests of interface conversions and type assertions. | 
|  |  | 
|  | type I0 interface { | 
|  | } | 
|  | type I1 interface { | 
|  | f() | 
|  | } | 
|  | type I2 interface { | 
|  | f() | 
|  | g() | 
|  | } | 
|  |  | 
|  | type C0 struct{} | 
|  | type C1 struct{} | 
|  |  | 
|  | func (C1) f() {} | 
|  |  | 
|  | type C2 struct{} | 
|  |  | 
|  | func (C2) f() {} | 
|  | func (C2) g() {} | 
|  |  | 
|  | func main() { | 
|  | var i0 I0 | 
|  | var i1 I1 | 
|  | var i2 I2 | 
|  |  | 
|  | // Nil always causes a type assertion to fail, even to the | 
|  | // same type. | 
|  | if _, ok := i0.(I0); ok { | 
|  | panic("nil i0.(I0) succeeded") | 
|  | } | 
|  | if _, ok := i1.(I1); ok { | 
|  | panic("nil i1.(I1) succeeded") | 
|  | } | 
|  | if _, ok := i2.(I2); ok { | 
|  | panic("nil i2.(I2) succeeded") | 
|  | } | 
|  |  | 
|  | // Conversions can't fail, even with nil. | 
|  | _ = I0(i0) | 
|  |  | 
|  | _ = I0(i1) | 
|  | _ = I1(i1) | 
|  |  | 
|  | _ = I0(i2) | 
|  | _ = I1(i2) | 
|  | _ = I2(i2) | 
|  |  | 
|  | // Non-nil type assertions pass or fail based on the concrete type. | 
|  | i1 = C1{} | 
|  | if _, ok := i1.(I0); !ok { | 
|  | panic("C1 i1.(I0) failed") | 
|  | } | 
|  | if _, ok := i1.(I1); !ok { | 
|  | panic("C1 i1.(I1) failed") | 
|  | } | 
|  | if _, ok := i1.(I2); ok { | 
|  | panic("C1 i1.(I2) succeeded") | 
|  | } | 
|  |  | 
|  | i1 = C2{} | 
|  | if _, ok := i1.(I0); !ok { | 
|  | panic("C2 i1.(I0) failed") | 
|  | } | 
|  | if _, ok := i1.(I1); !ok { | 
|  | panic("C2 i1.(I1) failed") | 
|  | } | 
|  | if _, ok := i1.(I2); !ok { | 
|  | panic("C2 i1.(I2) failed") | 
|  | } | 
|  |  | 
|  | // Conversions can't fail. | 
|  | i1 = C1{} | 
|  | if I0(i1) == nil { | 
|  | panic("C1 I0(i1) was nil") | 
|  | } | 
|  | if I1(i1) == nil { | 
|  | panic("C1 I1(i1) was nil") | 
|  | } | 
|  | } |