基本数据类型
1.整型
Go语言同时提供了有符号和无符号的整数类型。
- 有符号整型:int、int8、int64、int32、int64
- 无符号整型:uint、uint8、uint64、uint32、uint64、uintptr
有符号整型范围:
-2^(n-1) 到 2^(n-1)-1
无符号整型范围:
0 到 2^n-1
实际开发中由于编译器和计算机硬件的不同,int 和 uint 所能表示的整数大小会在 32bit 或 64bit 之间变化
用来表示 Unicode 字符的 rune 类型
和 int32 类型
是等价的,通常用于表示一个 Unicode 码点
。这两个名称可以互换使用;
同样,byte
和 uint8
也是等价类型,byte 类型一般用于强调数值是一个原始的数据
而不是一个小的整数
无符号的整数类型
uintptr
,它没有指定具体的 bit 大小但是足以容纳指针。uintptr 类型只有在底层编程
时才需要,特别是Go语言和C语言函数库或操作系统接口相交互的地方。
2.浮点型
var 变量名 float32/float64
float32
:范围 约1.4e-45 到 约3.4e38;单精度浮点数,占用32位(4字节);其中1位用于符号位,8位用于指数,剩余的23位用于尾数float64
:范围约4.9e-324 到 约1.8e308;双精度浮点数,占用64位(8字节);其中1位用于符号位,11位用于指数,剩余的52位用于尾数
3.布尔型
var 变量名 bool
==
,>
,<
,<=
, >=
,&&(AND)
,||(OR)
等都会产生bool值
&&(AND)
,||(OR)
是具有短路行为的,如果运算符左边的值已经可以确定整个布尔表达式的值,那么运算符右边的值将不再被求值。(&&优先级高于||)
布尔型数据只有true和false,且不能参与任何计算以及类型转换
4.字符类型
Go语言的字符有以下两种:
- 一种是
uint8
类型,或者叫byte
型,代表了 ASCII 码的一个字符。 - 另一种是
rune
类型,代表一个 UTF-8 字符,当需要处理中文、日文或者其他复合字符时,则需要用到 rune 类型。rune
类型等价于int32
类型。
byte 类型是 uint8 的别名,rune 类型是int32的别名
ASCII 码的一个字符占一个字节
ASCII 定义 128 个字符,由码位 0 – 127 标识。它涵盖英文字母,拉丁数字和其他一些字符
5.字符串型
var 变量名 string
字符串是一种值类型,且值不可变,即创建某个文本后将无法再次修改这个文本的内容。
当字符为 ASCII 码表上的字符时则占用 1 个字节
字符串中可以使用转义字符来实现换行、缩进等效果,常用的转义字符包括:
\n:
换行符\r:
回车符\t:
tab 键\u 或 \U:
Unicode 字符- \:反斜杠自身
如果使用``反引号,会被原样进行赋值和输出
5.1 字符串的应用
一般的比较运算符(==、!=、<、<=、>=、>)是通过在内存中按字节比较来实现字符串比较的,因此比较的结果是字符串自然编码的顺序。
字符串所占的字节长度可以通过函数 len() 来获取,例如 len(str)。
字符串的内容(纯字节)可以通过标准索引法来获取,在方括号[ ]
内写入索引,索引从 0 开始计数:
- 字符串 str 的第 1 个字节:str[0]
- 第 i 个字节:str[i - 1]
- 最后 1 个字节:str[len(str)-1]
⚠️:获取字符串中某个字节的地址属于非法行为,例如 &str[i]
5.1.1 字符串拼接符“+”
两个字符串 s1 和 s2 可以通过 s := s1 + s2 拼接在一起。将 s2 追加到 s1 尾部并生成一个新的字符串 s
str := "第一部分 " + "第二部分"
也可以使用“+=”来对字符串进行拼接:
s := "hel" + "lo,"
s += "world!"
fmt.Println(s) //输出 “hello, world!”
除了使用+
进行拼接,我们也可以使用WriteString()
str1 := "你好,"
str2 := "我是yama"
var stringBuilder bytes.Buffer
//节省内存分配,提高处理效率
stringBuilder.WriteString(str1)
stringBuilder.WriteString(str2)
fmt.Println(stringBuilder.String()) // 你好,我是yama
5.1.2 遍历
unicode字符集使用for range
进行遍历,ascii字符集可以使用for range
或者for
循环遍历
var str1 string = "hello"
var str2 string = "hello,我是yama"
// 遍历
for i := 0; i < len(str1); i++ {
fmt.Printf("ascii: %c %d\n", str1[i], str1[i])
}
for _, s := range str1 {
fmt.Printf("unicode: %c %d\n ", s, s)
}
// 中文只能用 for range
for _, s := range str2 {
fmt.Printf("unicode: %c %d\n ", s, s)
}
//ascii: h 104
//ascii: e 101
//ascii: l 108
//ascii: l 108
//ascii: o 111
//unicode: h 104
//unicode: e 101
//unicode: l 108
//unicode: l 108
//unicode: o 111
//unicode: h 104
//unicode: e 101
//unicode: l 108
//unicode: l 108
//unicode: o 111
//unicode: , 44
//unicode: 我 25105
//unicode: 是 26159
//unicode: y 121
//unicode: a 97
//unicode: m 109
//unicode: a 97
5.1.3 字符串的格式化
print :
结果写到标准输出Sprint:
结果会以字符串形式返回
%c 单一字符
%T 动态类型
%v 本来值的输出
%+v 字段名+值打印
%d 十进制打印数字
%p 指针,十六进制
%f 浮点数
%b 二进制
%s string
5.1.4 字符串查找
strings.Index()
: 正向搜索子字符串strings.LastIndex()
:反向搜索子字符串
// 查找
tracer := "张三来了,张三bye bye"
// 正向搜索字符串
comma := strings.Index(tracer, ",")
fmt.Println(",所在的位置:", comma) // ,所在的位置: 12
fmt.Println(tracer[comma+1:]) // 张三bye bye
add := strings.Index(tracer, "+")
fmt.Println("+所在的位置:", add) // +所在的位置: -1
pos := strings.Index(tracer[comma:], "张三")
fmt.Println("张三,所在的位置", pos) // 张三,所在的位置 1
fmt.Println(comma, pos, tracer[5+pos:]) // 12 1 来了,张三bye bye
5.1.5 修改字符串
Golang语言的字符串是不可变的
修改字符串时,可以将字符串转换为[]byte
进行修改
[]byte和string可以通过强制类型转换
将8080改为8081
s1 := "localhost:8080"
fmt.Println(s1)
// 强制类型转换 string to byte
strByte := []byte(s1) // localhost:8080
// 下标修改
strByte[len(s1)-1] = '1'
fmt.Println(strByte) // [108 111 99 97 108 104 111 115 116 58 56 48 56 49]
// 强制类型转换 []byte to string
s2 := string(strByte)
fmt.Println(s2) // localhost:8081
6. 类型转换
一个类型的值可以被转换成另一种类型的值。由于Go语言不存在隐式类型转换,因此所有的类型转换都必须显式的声明:
//类型 B 的值 = 类型 B(类型 A 的值)
valueOfTypeB = type B(valueOfTypeA)
a := 5.0
b := int(a)
fmt.Printf("%v,%T\n", a, a) // 5,float64
fmt.Printf("%v,%T", b, b) // 5,int
类型转换只能在定义正确的情况下转换成功,例如从一个取值范围较小的类型转换到一个取值范围较大的类型(将 int16 转换为 int32)
当从一个取值范围较大的类型转换到取值范围较小的类型时(将 int32 转换为 int16 或将 float32 转换为 int),会发生精度丢失
的情况。