// run // Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Tests type assertion expressions and statements package main import ( "fmt" "runtime" ) type ( S struct{} T struct{} I interface { F() } ) var ( s *S t *T ) func (s *S) F() {} func (t *T) F() {} func e2t_ssa(e interface{}) *T { return e.(*T) } func i2t_ssa(i I) *T { return i.(*T) } func testAssertE2TOk() { if got := e2t_ssa(t); got != t { fmt.Printf("e2t_ssa(t)=%v want %v", got, t) failed = true } } func testAssertE2TPanic() { var got *T defer func() { if got != nil { fmt.Printf("e2t_ssa(s)=%v want nil", got) failed = true } e := recover() err, ok := e.(*runtime.TypeAssertionError) if !ok { fmt.Printf("e2t_ssa(s) panic type %T", e) failed = true } want := "interface conversion: interface {} is *main.S, not *main.T" if err.Error() != want { fmt.Printf("e2t_ssa(s) wrong error, want '%s', got '%s'\n", want, err.Error()) failed = true } }() got = e2t_ssa(s) fmt.Printf("e2t_ssa(s) should panic") failed = true } func testAssertI2TOk() { if got := i2t_ssa(t); got != t { fmt.Printf("i2t_ssa(t)=%v want %v", got, t) failed = true } } func testAssertI2TPanic() { var got *T defer func() { if got != nil { fmt.Printf("i2t_ssa(s)=%v want nil", got) failed = true } e := recover() err, ok := e.(*runtime.TypeAssertionError) if !ok { fmt.Printf("i2t_ssa(s) panic type %T", e) failed = true } want := "interface conversion: main.I is *main.S, not *main.T" if err.Error() != want { fmt.Printf("i2t_ssa(s) wrong error, want '%s', got '%s'\n", want, err.Error()) failed = true } }() got = i2t_ssa(s) fmt.Printf("i2t_ssa(s) should panic") failed = true } func e2t2_ssa(e interface{}) (*T, bool) { t, ok := e.(*T) return t, ok } func i2t2_ssa(i I) (*T, bool) { t, ok := i.(*T) return t, ok } func testAssertE2T2() { if got, ok := e2t2_ssa(t); !ok || got != t { fmt.Printf("e2t2_ssa(t)=(%v, %v) want (%v, %v)", got, ok, t, true) failed = true } if got, ok := e2t2_ssa(s); ok || got != nil { fmt.Printf("e2t2_ssa(s)=(%v, %v) want (%v, %v)", got, ok, nil, false) failed = true } } func testAssertI2T2() { if got, ok := i2t2_ssa(t); !ok || got != t { fmt.Printf("i2t2_ssa(t)=(%v, %v) want (%v, %v)", got, ok, t, true) failed = true } if got, ok := i2t2_ssa(s); ok || got != nil { fmt.Printf("i2t2_ssa(s)=(%v, %v) want (%v, %v)", got, ok, nil, false) failed = true } } var failed = false func main() { testAssertE2TOk() testAssertE2TPanic() testAssertI2TOk() testAssertI2TPanic() testAssertE2T2() testAssertI2T2() if failed { panic("failed") } }