Golang类型转换小结

1. 类型转换方式

1.1. 强制类型转换

  1. 语法:<结果类型> := <目标类型> ( <表达式> )
  2. 类型转换是用来在不同但相互兼容的类型之间的相互转换的方式,所以,当类型不兼容的时候,是无法转换的。
func main() {
    //整型int强转为浮点型,强转为int64
    var num1 int = 17
    var num2 float32
    var num3 int64
    num2 = float32(num1) 
    num3 = int64(num1)

    //int64强转为int32
    var a int64 = 3
    var b int32
    b = int32(a)   
}

1.2. 类型断言

类型转换,适用接口

<目标类型的值>,<布尔参数> := <表达式>.( 目标类型 ) // 安全类型断言
<目标类型的值> := <表达式>.( 目标类型 )   //非安全类型断言

func main(key interface{}, value interface{}) error {
    fmt.Println("interface change type")
    k, ok := key.(string)
    if ok {
        fmt.Printf("key=%s\n", k)
    }
    // keystr := key.(string)
    // fmt.Printf("key=%s", keystr)
    var valstr []byte
    switch v := value.(type) {
    case string:
        valstr = []byte(v)
    case []byte:
        valstr = v
    case int:
        fmt.Println(v)
    default:
        return errors.New("value type not supported")
    }
    fmt.Printf("val=%s\n", string(valstr)) //string初始化函数转换 []byte-》string
    return nil
}

1.3. 函数转换

1.3.1. strconv: string <=> 数字类型

// strconv  string  => 数字类型
func StingToNumTest() (err error) {
    var str string = "104"
    var int1 int = 103
    var int64_1 int64 = 102
    //string转成int:
    int1, err = strconv.Atoi(str)
    fmt.Printf("%T=%d\n", int1, int1)
    //string转成int64:
    int64_1, err = strconv.ParseInt(str, 10, 64)
    fmt.Printf("%T=%d\n", int64_1, int64_1)
    return
}

// strconv  string  <= 数字类型
func NumToStringTest(){
    // f 格式  // 10 小数位保留10位  // 64  表示float64
    var num2 float64 = 66.66
    var b1 bool = true
    var int2 int = 103
    //int转成string:
    str = strconv.Itoa(int2)
    fmt.Printf("%T=%s\n", str, str)
    //int64转成string:
    str = strconv.FormatInt(int64_1, 10)
    fmt.Printf("%T=%s\n", str, str)
    str2 := strconv.FormatFloat(num2, 'f', 10, 64)
    fmt.Printf("str2类型是%T str2=%q\n", str2, str2)
    str3 := strconv.FormatBool(b1)
    fmt.Printf("str3类型是%T str3=%q\n", str3, str3)
}

1.3.2. fmt.Sprintf: 数字或结构体 => 字符串

// Sprintf   数字或结构体 => 字符串
func InterfaceToStringTest() {
    var num1 int = 66
    var num2 float64 = 25.25
    var b bool = true
    var myChar byte = 'c'
    //%q 单引号
    //%d 十进制表示
    str1 := fmt.Sprintf("%d", num1)
    fmt.Printf("str1 type %T str=%q\n", str1, str1)
    //%f 小数点
    str2 := fmt.Sprintf("%f", num2)
    fmt.Printf("str2 type %T str2=%q\n", str2, str2)
    //%t 布尔值
    str3 := fmt.Sprintf("%t", b)
    fmt.Printf("str3 type %T str3=%q\n", str3, str3)
    //%c Unicode码对应的字符
    str4 := fmt.Sprintf("%c", myChar)
    fmt.Printf("str4 type %T str4=%q\n", str4, str4)
}

1.3.3. binary.BigEndian/LittleEndian

2. 类型转换

2.1. 字符串和数字互转


//StrToUint16 string to uint16
func StrToUint16(str string) uint16 {
    j, err := strconv.ParseInt(str, 10, 16)
    if err == nil {
        //fmt.Printf("_uint16: %v\n", int16(j))
        return uint16(j)
    }
    return uint16(0)
}

//StrToUint32 string to uint32
func StrToUint32(str string) uint32 {
    j, err := strconv.ParseInt(str, 10, 32)
    if err == nil {
        //fmt.Printf("_uint32: %v\n", int32(j))
        return uint32(j)
    }
    return uint32(0)
}

func StrToUint32_2(str string) int {
    num, err := strconv.Atoi(str)
    if err != nil {
        panic(err)
    }
    return num
}

var regSN = regexp.MustCompile("^01[0-9a-fA-F]{6}$")

var sn = "01012345"

//sn format 01xxxxxx, length 8, 01-abc1000, xxxxxx-hex char
func checkSN(sn string) bool {
    return regSN.MatchString(sn)
}

func StrToUint64(sn string) uint64 {
    var nr1 uint64 = 0
    check := checkSN(sn) //正则匹配,校验字符串
    if check {
        nr1, err := strconv.ParseUint(sn[:4], 16, 16)
        if err != nil {
            return 0
        }
        fmt.Sprintf("%x", nr1) //打印16进制
    }
    return nr1
}

//方法1 fmt
func Uint32ToStr(num uint32) string {
    return fmt.Sprintf("%d", num)
}

//方法2 strconv
func Uint32ToStr2(num uint32) string {
    return strconv.Itoa(int(num))
}

2.2. byte数组 和 字符串 互转

func StrToBytes(s string) []byte {
    //原有var b = string(a) 转换性能较差
    x := (*[2]uintptr)(unsafe.Pointer(&s))
    h := [3]uintptr{x[0], x[1], x[1]}
    return *(*[]byte)(unsafe.Pointer(&h))
    // x := *(*reflect.StringHeader)(unsafe.Pointer(&s))
    // return *(*[]byte)(unsafe.Pointer(&x))
}

func BytesToStr(b []byte) string {
    //原有var a = []byte("hello boy")    转换性能较差
    return *(*string)(unsafe.Pointer(&b))
}

func testByteStr() {
    s := strings.Repeat("abc", 3)
    b := StrTobytes(s)
    s2 := BytesTostr(b)
    fmt.Println(b, s2)
}

2.3. byte数组 和 数字互转

//这里入参为小端uint32, 调换顺序转换为大端,输出[]byte大端;例如输入0.0.

func Uint32ToBytes(num uint32) []byte {
    buf := make([]byte, 4)
    binary.LittleEndian.PutUint32(buf, num)
    fmt.Printf("%x:%x:%x:%x", buf[0], buf[1], buf[2], buf[3])
    return buf
}

func BytesToUint32(buf []byte) uint32 {
    return binary.LittleEndian.Uint32(buf) //这里不会转换字节序,若需转换改为 BigEndian
}

/*
func (littleEndian) PutUint32(b []byte, v uint32) {
    _ = b[3] // early bounds check to guarantee safety of writes below
    b[0] = byte(v)
    b[1] = byte(v >> 8)
    b[2] = byte(v >> 16)
    b[3] = byte(v >> 24)
}
func (littleEndian) Uint32(b []byte) uint32 {
    _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
    return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
}
*/

发表评论

邮箱地址不会被公开。 必填项已用*标注