Go语言中的数据类型转换技巧

发表时间: 2023-10-19 09:53

golang数据类型

基本类型:boolean, numeric, string类型的命名实例是预先声明的。

复合类型:array, struct, 指针, function, interface, slice, map, channel类型(可以使用type构造)。

整型之间的转换(int, int8, int32, int64)

int => int32

i32 = int32(num)

int => int64

i64 = int64(num)

int64/int32 => int

i = int(num)

实例:

package mainimport (    "fmt"    "reflect")func main() {    var num int = 12    i8 := int8(num)    i32 := int32(num)    i64 := int64(num)    var i = int(i64)    fmt.Println(num, i8, i32, i64, i) //12 12 12 12 12    fmt.Println(reflect.TypeOf(num), reflect.TypeOf(i8), reflect.TypeOf(i32), reflect.TypeOf(i64), reflect.TypeOf(i)) //int int8 int32 int64 int}

整型(int, int8, int32, int64)与浮点数(float32, float64)之间的转换

int, int8, int32, int64 => float32, float64

float32(num)

float64(num)

float64/float32 => int, int8, int32, int64

int(price)

int8(price)

int32(price)

int64(price)

实例:

package mainimport (    "fmt"    "reflect")func main() {    var num int64 = 32    fmt.Println(float32(num)) //32    fmt.Println(reflect.TypeOf(float32(num))) //float32    var price float32 = 8.14    fmt.Println(int8(price)) //8    fmt.Println(reflect.TypeOf(int8(price))) //int8    fmt.Println(int64(price)) //8    fmt.Println(reflect.TypeOf(int64(price))) //int64}

综上所述: 整型与浮点数内部之间的转换GO语言都提供了内建函数int, int8, int32, int64, float32, float64, 他们之间可以任意进行转换

整型(int和uint)和字符串型(string)转换

int => string

语法: func Itoa(i int) string

s = strconv.Itoa(i)

注意: Itoa是FormatInt(i, 10) 的简写, 只是少传递一个参数, 但是传递的参数类型只能为 int 类型

int64 => string

语法: func FormatInt(i int64, base int) string

s = strconv.FormatInt(i, 10)

uint => string

func FormatUint(i uint64, base int) string

s = strconv.FormatUint(ui)

string => int

语法: func Atoi(s string) (i int, err error)

i, err = strconv.Atoi(s)

注意: Atoi是ParseInt(s, 10, 0)的简写, 只是少传递两个参数。

string => int8/int/int32/int64

func ParseInt(s string, base int, bitSize int) (i int64, err error)

base指定进制(2到36), 如果base为0, 则会从字符串前置判断, "0x"是16进制, "0"是8进制, 否则是10进制;

bitSize指定结果必须能无溢出赋值的整数类型 0、8、16、32、64 分别代表 int、int8、int16、int32、int64base指定进制(2到36), 如果base为0, 则会从字符串前置判断, "0x"是16进制, "0"是8进制, 否则是10进制;

bitSize指定结果必须能无溢出赋值的整数类型 0、8、16、32、64 分别代表 int、int8、int16、int32、int64

s, err = strconv.ParseInt(i, 10, 64)

string => uint

func ParseUint(s string, base int, bitSize int) (n uint64, err error)

s, err = strconv.ParseUint(ui)

实例:

package mainimport (    "fmt"    "reflect"    "strconv")func main() {    var num int = 32    str := strconv.Itoa(num) //整型转换为字符串型    var old string = "128"    age, err := strconv.Atoi(old) //字符串型转换为整型    if err != nil {    fmt.Println("Atoi 返回值需要用两个变量接收")    }    fmt.Println(reflect.TypeOf(str), reflect.TypeOf(age)) //string int}

实例:

package mainimport (    "fmt"    "reflect"    "strconv")func main() {    var num int64 = 32    str := strconv.FormatInt(num, 10) //整型转化为字符串型    var old string = "128"    age, err := strconv.ParseInt(old, 10, 32) //字符串型转化为整型    if err != nil {    fmt.Println("Atoi 返回值需要用两个变量接收")    }    fmt.Println(reflect.TypeOf(str), reflect.TypeOf(age)) //string int64}

float 转换 string

float32 => string

float64 => string

float32需要先转换为float64, 然后转换为string

实例:

package main //必须有个main包import (    "fmt"    "strconv")func main() {    //浮点型转换为字符串型    var num1 float32 = 87.8    var num2 float64 = 98.3    fmt.Println(strconv.FormatFloat(float64(num1), 'f', 1, 64)) //float32先转换为float64    fmt.Println(strconv.FormatFloat(num2, 'f', 1, 64))}//float32 转 String工具类,保留6位小数func FloatToString(input_num float32) string {    // to convert a float number to a string    return strconv.FormatFloat(float64(input_num), 'f', 6, 64)}

综上所述: 字符串(string)与整形、浮点型、布尔型之间的转换使用strconv包进行转换, 如: strconv.ParseInt()、strconv.FormatInt()

[]byte与其他类型转换

[]byte => string: 使用内建函数string()

[]byte => int

package main //必须有个main包import (    "bytes"    "encoding/binary"    "fmt")func main() {    //[]byte 转换为 string    var str = []byte{65, 67, 68, 69}    fmt.Println(string(str)) //ACDE    //[]byte类型转换int类型:    b := []byte{0, 0, 0, 35}    bin_buf := bytes.NewBuffer(b)    var x int32    binary.Read(bin_buf, binary.BigEndian, &x)    fmt.Println(x) //35}

string => []byte: 使用内建函数[]byte()

package mainimport (    "fmt"    "reflect")func main() {    var s string = "this is string"    b := []byte(s)    fmt.Println(b, reflect.TypeOf(b))}

int =>[]byte

package mainimport (    "bytes"    "encoding/binary"    "fmt")func main() {    var i1 int64 = 511 // [00000000 00000000 ... 00000001 11111111] = [0 0 0 0 0 0 1 255]    s1 := make([]byte, 0)    buf := bytes.NewBuffer(s1) //等同于 buf := bytes.NewBuffer([]byte{})    // int64  []byte, 网络字节序为大端字节序    binary.Write(buf, binary.BigEndian, i1)    fmt.Println(buf.Bytes()) //[0 0 0 0 0 0 1 255]    // int64  []byte, 网络字节序为小端字节序    buf.Reset()    binary.Write(buf, binary.LittleEndian, i1)    fmt.Println(buf.Bytes()) //[255 1 0 0 0 0 0 0]}

注意: int64 转 []byte, 网络字节序为大端字节序, GO语言编程一般采用大端字节序

array(数组) 与 slice(切片) 之间转换

array 转换成 slice (array => slice)

实例: array => slice 第一种方法

package mainimport (    "fmt"    "reflect")func main() {    s := [3]int{1, 2, 3}    var a []int    var b []int    a = s[:] //获取全部    b = s[0:2] //获取部分    fmt.Println(a, b) //[1 2 3] [1 2]    fmt.Println(reflect.TypeOf(a), reflect.TypeOf(b)) //[]int []int}

实例: array => slice 第二种方法

package mainimport (    "fmt"    "reflect")func main() {    s := [3]int{1, 2, 3}    //var a []int 虽然切片可以这样定义, 但是此种定义方法 导致for遍历时会出现错误    var a = make([]int, 3) //切片的定义方法    for index, item := range s {        a[index] = item    }    fmt.Println(a, reflect.TypeOf(a)) //[1 2 3] []int}

slice 转换成 array (slice => array)

实例:

package mainimport (    "fmt"    "reflect")func main() {    s := []int{1, 2, 3} //切片的定义方法    a := s[:] //全部拷贝, 实际相当于转换    fmt.Println(a, reflect.TypeOf(a)) //[1 2 3] []int}

实例: 如何获取数据的类型

package mainimport (    "fmt"    "reflect"    "strconv")var x = 100func main() {    var s = strconv.Itoa(x)    var z = int32(x)    fmt.Println(reflect.TypeOf(x), reflect.TypeOf(s), reflect.TypeOf(z), reflect.TypeOf(int64(x))) //int string int32 int64}

数据类型说明

1. int类型中哪些支持负数

有符号(负号):int8 int16 int32 int64

无符号(负号):uint8 uint16 uint32 uint64

2. 浮点类型的值有float32和float64(没有 float 类型)

3. byte和rune特殊类型是别名

byte就是unit8的别名

rune就是int32的别名

4. int和uint取决于操作系统(32位机器上就是32字节, 64位机器上就是64字节)

uint是32字节或者64字节

int和uint是一样的大小

5. 为了避免可移植性问题, 除了byte(它是uint8的别名)和rune(它是int32的别名)之外, 所有数字类型都是不同的。

在表达式或赋值中混合使用不同的数字类型时, 需要转换。例如, int32和int不是相同的类型, 即使它们可能在特定架构上具有相同的大小。

6 int 与 []byte 之前的转换使用 encoding/binary 包进行转换

实战: 封装函数

package mainimport (    "fmt"    "encoding/binary")func Int64ToBytes(i int64) []byte {    var buf = make([]byte, 8)    binary.BigEndian.PutUint64(buf, uint64(i))    return buf}func BytesToInt64(buf []byte) int64 {    return int64(binary.BigEndian.Uint64(buf))}func main() {    var i int64 = 2323    buf := Int64ToBytes(i)    fmt.Println(buf)    fmt.Println(BytesToInt64(buf))}