内容目录
概述
go中的数据类型有四大类型:基础类型,聚合类型,引用类型和接口类型
我们今天来唠基础类型。
go的基本数据类型和其他语言差不多的,主要有:
- 整数
- 浮点数
- 复数
- 布尔
- 字符串
- 常量
先来背书
整数
整数的类型还是挺多的,分为两类:无符号有和有符号。
有C语言学习经验的朋友们对这个还是比较熟悉的,Java的朋友们平时用的都是有符号。
- 有符号:signed
- 无符号:unsigned
有符号整型
- int
- int8
- int16
- int32
- int64
带有数字的(8,16,32,64)这些表示位数,分别表示单字节,双字节,四字节和八字节。
长度范围:
这四种类型大家根据自己的需求来使用就行了。
唯一一个特殊的就是int,这个是多少位?32还是64?这个根据计算机系统体系结构来定,如果你是32位的操作系统,那它就是32位;如果你是64位的操作系统它就是64位。
那int什么时候用?
- 你调用的库函数返回了int,你得用int接收
- 你评估不管int是32位还是64位都能满足你的需求,比如:for循环,你只循环10次,用int没毛病
- 在多种类型之间犹豫不决的时候就选int
- 听说还是有性能和通用性问题,性能我不好测试就不多说了
怎么确定你的int的位数?
无符号整型
- uint
- uint8
- uint16
- uint32
- uint64
- uintptr
无符号和有符号类似,这里给一下范围就好了:
这里得单独提一下uintptr,这个特殊类型其实就是我们的内存地址,准确说是程序逻辑地址空间中的地址;用它可以直接操作内存,举个例子:
假设我们有一个数组,数组有两个元素,int[]{42, 43}。我们要知道数组中的元素在内存中都是一个接着一个存储的:42|43,那我们就可以用uintptr来获取42的地址,然后+size(int)的偏移就可以获取43的地址;或者反过来:先获取43的地址然后-size(int)的偏移就可以获取42的地址。
具体来看个代码:
import (
"fmt"
"unsafe"
)
func main() {
var x []int = make([]int, 2)
x[0] = 42
x[1] = 43
// 获取第一个元素:42的地址
firstElementPtr := unsafe.Pointer(&x[0])
// 计算第二个元素的地址
// 确保我们根据 int 类型的大小来移动指针
secondElementPtr := unsafe.Pointer(uintptr(firstElementPtr) + unsafe.Sizeof(x[0]))
// 通过 secondElementPtr 获取第二个元素的值
secondElementValue := *(*int)(secondElementPtr)
fmt.Printf("The value of the second element is: %d\n", secondElementValue)
}
代码输出如下(我们是通过42的地址取43的地址):
浮点数
- float32
- float64
浮点数就比较普通了,就是两种类型:单精度和双精度。
// 使用 float32 类型
var f1 float32 = 3.14159
fmt.Printf("The value of f1 (float32) is: %f\n", f1)
// float64 类型,同时展示科学计数法
var f2 float64 = 1.61803398875
fmt.Printf("The value of f2 (float64) is: %.8f (formatted with 8 digits)\n", f2)
// 直接使用浮点字面量,这些默认为 float64 类型
f3 := 123.456
fmt.Printf("The value of f3 (implicit float64) is: %f\n", f3)
复数
- complex64
- complex128
这个得有点数学功底了,这个我平时是不咋常用,科学计算,电子和信号处理用的比较多吧。
布尔
- bool
布尔类型,就是true和false。
var isCorrect bool = false
var isCorrect bool = true
字符串
- string
字符串在日常中用的非常多的,go也提供了很多常用字符串函数,字符串函数在strings包中: - Contains
- Count
- HasPrefix
- HasSuffix
- Index
- Join
- Replace
- Split
- ToLower/ToUpper
10.Trim - …
字节(byte)
- byte
byte其实就是整型的uint8,可以让我们处理原始数据和文本数据,比如:处理网络数据包和文本文件等。
var b byte = 'A'
常量
- const
常量就是一旦一定就不可变的值,也是非常常用。
// 全局常量的定义
const a = 1
// 同时定义多个常量
const (
HttpStatusCodeOK = 200
HttpStatusCodeNotFound = 404
)
const (
PAY_STATUS_CREATE = iota
PAY_STATUS_PAYING
PAY_STATUS_PAIED
...
)
上面的例子中有一个iota
,这个是go中预声明标识符,表示后面的数值依次递增,初始值为0,也是会上面的PAY_STATUS_CREATE为0,PAY_STATUS_PAYING为1,PAY_STATUS_PAIED为2。
基础类型转换
go类型转换必须是显式的,go不会进行自动转换。
整数之间的转换:
var i int32 = 42
var j int64 = int64(i) // 将 int32 类型的 i 转换为 int64 类型
浮点数到整数:
var f float64 = 3.14
var k int = int(f) // 将 float64 类型的 f 转换为 int 类型,小数部分将丢失
整数到字符串:
var num int = 97
var s string = string(rune(num)) // 将 int 类型的 num 转换为对应 ASCII 代码的字符后进行字符串转换
import "strconv"
var num int = 97
var s string = strconv.Itoa(num) // 将 int 类型的 num 转换为 string 类型