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()

 

posted @ 2022-11-15 16:16  许伟强  阅读(831)  评论(0编辑  收藏  举报