前言
Go的基本类型有:
- int8, int16, int32, int64, int
- uint8, uint16, uint32, uint64, uint
- float32, float64
- complex64, complex128
- bool
- byte
- rune
- string
整型
有符号整型
int8:表示 8 位有符号整型(00000000 ~ 11111111, 第一位是符号位)
大小:8 位
范围:-128~127
int16:表示 16 位有符号整型
大小:16 位
范围:-32768~32767
int32:表示 32 位有符号整型
大小:32 位
范围:-2147483648~2147483647
int64:表示 64 位有符号整型
大小:64 位
范围:-9223372036854775808~9223372036854775807
int:根据不同的底层平台自动选择 32 或 64 位整型。除非对整型的大小有特定的需求,否则你通常应该使用int
表示整型。
无符号整型
uint8:表示 8 位无符号整型
大小:8 位
范围:0~255
uint16:表示 16 位无符号整型
大小:16 位
范围:0~65535
uint32:表示 32 位无符号整型
大小:32 位
范围:0~4294967295
// 之前遇到的一个坑:想判定时间戳是否符合规范,且习惯用uint32,忘记考虑uint32的范围
func uint32diff64() {
a := uint32(math.Pow10(11)) // 1215752192
b := uint64(math.Pow10(11)) // 100000000000
fmt.Println(a, b)
}
uint64:表示 64 位无符号整型
大小:64 位
范围:0~18446744073709551615
uint:根据不同的底层平台,选择 32 或 64 位无符号整型。 在 32 位系统下是 32位 (0~4294967295),而在 64 位系统下是 64位 (0~18446744073709551615)。
如何查看字节数? 利用 unsafe.Sizeof
package main
import (
"fmt"
"unsafe"
)
func main() {
var a uint8 = 124
var b int = 2147483649
fmt.Println("size:", unsafe.Sizeof(a)) // 占1个字节
fmt.Println("size:", unsafe.Sizeof(b)) // 我的机器是64位,所以是8字节
}
浮点型
float32:32 位浮点数,占4个字节
float64:64 位浮点数,占8个字节
精度问题:mp.weixin.qq.com/s/wq_zt8gQg…
复数类型
复数类型的实部和虚部类型需一致,比如complex64
类型的实部和虚部都是 float32 类型;complex128
类型的实部和虚部都是 float64 类型
布尔类型
由于Go是强类型语言,所以0和false,1和true并不对等(在Python中是相等的)
# python
>>> True == 1
True
>>> False == 0
True
byte 和 rune
由于97可以理解为一个数字,也可以理解为字符a
(ASCII码),所以为了区分传递过来的到底是整型还是字符串(只是逻辑上的区分),诞生了byte和rune两种类型。
其中,byte是uint8 的别名,rune是int32的别名
func runeLab() {
var a uint8 = 97
var b byte = 97
fmt.Println(a == b) // True, a 和 b 本质一样,但逻辑含义不同
fmt.Println(a)
fmt.Println(string(b)) // "a"
}
零值
如果一个变量没有赋予初始值,则会被赋予它们的零值
,即默认值。
数值类型的零值为 0
布尔类型的零值为 false
字符串为的零值 ""(空字符串)
pointer, channel, func, interface, map, slice 类型的零值为nil
字符串类型
由于和其他语言相比,字符串在 Go 语言中有着自己特殊的实现,主要有以下几个特点。
- 1.字符串是字节的集合,即[]byte。
- 2.单引号和双引号代表的意义不同, 单引号是rune类型,双引号才是字符串类型。
- 3.多行字符串可用反引号表示,但不支持转义
func stringLab() {
name := "言淦"
fmt.Println([]byte(name)) // 本质是字节数组 [232 168 128 230 183 166]
// 多行字符串
multiStr := `Hello
World!`
fmt.Println(multiStr)
}
获取字符串长度
- 使用 bytes.Count() 统计
- 使用 strings.Count() 统计
- 将字符串转换为 []rune 后调用 len 函数进行统计
- 使用 utf8.RuneCountInString() 统计
str := "我是谁"
l1 := len([]rune(str)) // 3
l2 := bytes.Count([]byte(str), nil) - 1 // 3
l3 := strings.Count(str, "") - 1 // 3
l4 := utf8.RuneCountInString(str) // 3
字符串的格式化
类型转换
字符串和byte互转
func str2byte() {
name := "言淦"
nameBytes := []byte(name) // byte [232 168 128 230 183 166]
nameString := string(nameBytes) // 言淦
fmt.Println(nameBytes)
fmt.Println(nameString)
}
字符串和int互转
整型转字符串类型主要有三种方法:
- fmt.Sprintf:效率最低
- strconv.Itoa:效率第二位,封装了FormatInt
- strconv.FormatInt:效率最高
字符串转整型有两种办法:
- strconv.Atoi
- strconv.ParseInt
func str2int() {
// int --> string
var num int = 100
str1 := fmt.Sprintf("%d", num)
str2 := strconv.Itoa(num)
str3 := strconv.FormatInt(int64(num), 10)
fmt.Println(str1, str2, str3)
// string --> int
var str string = "100"
num1, _ := strconv.Atoi(str)
num2, _ := strconv.ParseInt(str, 10, 64)
fmt.Println(reflect.TypeOf(num1)) // int
fmt.Println(reflect.TypeOf(num2)) // int64
fmt.Println(num1, num2)
}