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") } }