1. 类型转换方式
1.1. 强制类型转换
- 语法:<结果类型> := <目标类型> ( <表达式> )
- 类型转换是用来在不同但相互兼容的类型之间的相互转换的方式,所以,当类型不兼容的时候,是无法转换的。
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
}
*/