golang类型强转
一、类型强转有些地方需要用到:
1. 结构体与结构体之间强转
2. 结构体指针转结构体指针
3. 基本数据类型之间转换
二、测试验证
1. 基本数据类型
// 显式转换 - 值类型 func TestTransfer(t *testing.T) { a := 1 b := 3.4 c := float64(a) * b t.Logf("c type=%T val=%v ", c, c) }
2. 结构体之间转换
type user struct { Name string } type student struct { Name string } func TestU(t *testing.T) { // 值直接转换为值 a := user{Name: "jack"} b := student(a) t.Logf("a type=%T val=%#v ", b, b) // 指针只能直接转换指针,如果 student(u) 无法编译 // 结构体类型指针直接转换 u := &user{Name: "rose"} s := (*student)(u) t.Logf("s type=%T val=%#v ", s, s) // 空指针直接转换 var z *user y := (*student)(z) t.Logf("y type=%T val=%#v ", y, y) var f int = 10 var h *int = &f var o *int64 // int和int64指针直接转换编译器报错因为有可能溢出改用unsafe // cannot convert p (type *int) to type *int64 // o = (*int64)(h) o = (*int64)(unsafe.Pointer(h)) t.Logf("o type=%T val=%#v ", o, o) }
3. 使用断言转换
// TestByAssert 通过类型断言的方式转换 func TestByAssert(t *testing.T) { // 无效的类型断言: u.(student) (左侧为非接口类型 user // 结构体不是接口类型 - 这里会编译报错 //u := user{Name: "rose"} //val, ok := u.(student) // 显式声明为interface就可以,意不意外 var u interface{} = user{Name: "rose"} if s, ok := u.(int64); ok { t.Logf("trans success s type=%T val=%#v ", s, s) } else { t.Log("user to int64 fail") } var a interface{} = 10 z, ok := a.(int) if ok { t.Logf("z=%T && %v", z, z) } t2, ok := a.(float32) if ok { t.Logf("t2=%T && %v", t2, t2) } else { t.Log("int to float32 fail") } }
这个转换经常被用来判定 某一个对象object是否是 某一个接口的实现 ,比如 github.com/pkg/errors 的 Cause 方法,判定是否是cause的实现,如果是就返回cause() 否则返回
原始错误
cause, ok := err.(causer) if !ok { break } err = cause.Cause()
I can see a bigger world.