Go语言基础 -- 基本数据类型及类型转换
1. 整型
1.1 整型分类
- 有符号整型:
int8、int16、int32、int64 - 无符号整型:
uint8、uint16、uint32、uint64
1.2 整形的取值范围
| 类型 | 长度(字节) | 默认值 | 说明 |
|---|---|---|---|
| byte | 1 | 0 | uint8 |
| rune | 4 | 0 | Unicode Code Point, int32 |
| int, uint | 4或8 | 0 | 32 或 64 位 |
| int8, uint8 | 1 | 0 | -128 ~ 127, 0 ~ 255,byte是uint8 的别名 |
| int16, uint16 | 2 | 0 | -32768 ~ 32767, 0 ~ 65535 |
| int32, uint32 | 4 | 0 | -21亿~ 21亿, 0 ~ 42亿,rune是int32 的别名 |
| int64, uint64 | 8 | 0 |
1.3 常用整型的别名
int8(8是表示8位, byte是int8的别名)- rune是
int32的别名,表示一个unicode码点
1.4 整型的底层存储
例如:int8,表示此数据类型占用空间为8位(1字节),
第一位为符号位,为0时,表示无符号, 为1时,表示有符号,剩余的7位表示数值,所以表示范围为2的-7到2的7次方-1(减得那个1是数值为0时,无需表示其正负),对于0表示时会有正0和-0,其实都是0所以负数部分就多了1个可以表示的数值
无符号的整数,特点是没有符号,所以第一位也可以表示数值本身,范围比有符号的要大一些,从0开始
1.5 整型操作
1.5.1 十进制转二,八,十六进制:
fmt.Println(strconv.FormatInt(132,2)) // 2 表示转成 二进制, 返回值为 string
fmt.Println(strconv.FormatInt(132,8)) // 8 表示转成 八进制, 返回值为 string
fmt.Println(strconv.FormatInt(132,16)) // 16 表示转成 十六进制, 返回值为 string
1.5 整型的注意事项
-
Golang中各整数类型分为:有符号和无符号,intuint的大小和操作系统有关 -
Golang的整形默认声明为int型 -
如何在程序查看某个变量的字节大小和数据类型
fmt.Printf("n1的类型为:%T",n1) // 查看变量的类型(%T) fmt.Printf("n1占用的字节数是:%d",n1,unsafe.Sizeof(n1)) // 查看变量的所占用的字节数 -
Golang中整型变量在使用时,遵守保小不保打的原则,即:在保证程序正确运行下,尽量使用占用空间小的数据类型,如年龄,不会为负数,最大为130+ 所以选用uint8(byte)最为合适 -
bit计算机中的最小存储单位,byte计算机中基本存储单元,1byte = 8bit
2. 浮点类型
2.1 浮点类型分裂
Go语言支持两种浮点型数,这两种浮点型数据格式遵循IEEE 754标准:
float32,最大范围约为3.4e38,可以使用内置常量定义:math.MaxFloat32float64,最大范围约为1.8e308,可以使用一个内置常量定义:math.MaxFloat64
2.2 浮点类型底层存储
浮点数在机器中存放的方式:浮点数 = 符号位+指数为+尾数位
示例:
3.56
//第一个字节表示符号位,第一位的1表示本浮点数为正数,.之前的是指数,.之后的是尾数
11110000111.11111111111111111000
//浮点型的存储分为三部分:符号位+指数位+尾数位,在存储过程中,精度会有丢失
2.3 注意事项
- 浮点类型有固定的范围和字段长度,不受具体OS(操作系统)的影响
- 浮点型默认声明为
float64类型 - 浮点型常量有两种方式表示
- 十进制数形式:如:5.12 0.512 可以用.512表示(必须有小数点)
- 科学计数法形式:如:
5.1234e2 = 5.12*10的2次方5.12E-2=5.12/10的2次方 - 通常情况下应该使用
float64,因为它比float32更准确,精度更高
2.4 复数(精度更高)
complex64
complex128
//复数有实部和虚部,complex64的实部和虚部为32位,complex128的实部和虚部为64位。
3. 布尔类型
布尔类型也叫bool类型,只允许取值true和false,占用1字节,通常用于逻辑运算,流程控制
注意事项
- 布尔类型变量的默认值为false
- Go 语言中不允许将整型强制转换为布尔型.
- 布尔型无法参与数值运算,也无法与其他类型进行转换。
4. 字符类型
4.1 字节序列
Go语言中没有专门的字符型,如果要存储单个字符(字母),一般使用byte来保存
字符串就是一串固定长度的字符连接起来的字符序列.
Go的字符串是由单个字节链接起来的,也就是说对于传统的字符串是由字符组成的,而Go的字符串不同,它是由字节组成的
4.2 单字符
func main() {
var s1 byte = 'a' // 如果保存的字符在ASICC表中,比如[0-1,a-z,A-Z],可以用byte类型保存,保存的是asicc码值
var s2 byte = '0'
var s3 int = '小' // 小 这个汉字的asicc码值不在 byte 能表示的值以内,所以需要更换数据类型,如果用byte存储会报overflow错误
fmt.Printf("s1的类型为: %T,值为%v,占用字节数为%d\n",s1,s1,unsafe.Sizeof(s1))
fmt.Printf("s2的类型为: %T,值为%v,占用字节数为%d\n",s2,s2,unsafe.Sizeof(s2))
fmt.Printf("s2的类型为: %T,值为%v,占用字节数为%d\n",s3,s3,unsafe.Sizeof(s3))
}
// 打印结果:
s1的类型为: uint8,值为97,占用字节数为1
s1的类型为: uint8,值为48,占用字节数为1
s2的类型为: int,值为23567,占用字节数为8
4.3 注意事项
-
字符常量是用单引号
'引起来的单个字符,var c1 byte = 'a' var c2 int = '中' var c3 byte = '9' -
Go中允许使用转义字符''来将其后的字符转变成特殊字符型常量
var c3 char = '\n' // \n 表示换行符 -
Go语言的字符使用
UTF-8编码 -
在Go中字符的本质是一个整体,直接输出时,是该字符对应的
UTF-8编码的码值 -
可以直接给某个变量赋一个数字,然后按格式化输出时
%c会输出改数字对应的Unicode字符 -
字符类型是可以进行运算的,单个字符类型的底层是
ascii码值,本质是个整数,因为它都对应有Unicode码
4.4 byte类型和rune类型
func main() {
s1 := "abcde真好"
for i := 0; i < len(s1); i++ {
fmt.Printf("第 %v个字符, 字符为: %c,ascii码值为: %v\r\n", i+1, s1[i], s1[i])
}
fmt.Println("rune循环开始!!!")
for i, v := range s1 {
fmt.Printf("第 %v个字符, 字符为: %c, utf-8码值为: %v\r\n", i+1, v, v)
}
}
// 输出结果:
第 1个字符, 字符为: a,ascii码值为: 97
第 2个字符, 字符为: b,ascii码值为: 98
第 3个字符, 字符为: c,ascii码值为: 99
第 4个字符, 字符为: d,ascii码值为: 100
第 5个字符, 字符为: e,ascii码值为: 101
第 6个字符, 字符为: ç,ascii码值为: 231
第 7个字符, 字符为: ,ascii码值为: 156
第 8个字符, 字符为: ,ascii码值为: 159
第 9个字符, 字符为: å,ascii码值为: 229
第 10个字符, 字符为: ¥,ascii码值为: 165
第 11个字符, 字符为: ½,ascii码值为: 189
rune循环开始!!!
第 1个字符, 字符为: a, utf-8码值为: 97
第 2个字符, 字符为: b, utf-8码值为: 98
第 3个字符, 字符为: c, utf-8码值为: 99
第 4个字符, 字符为: d, utf-8码值为: 100
第 5个字符, 字符为: e, utf-8码值为: 101
第 6个字符, 字符为: 真, utf-8码值为: 30495
第 9个字符, 字符为: 好, utf-8码值为: 22909
4.5 字符类型的底层存取过程
-
字符型存储到计算机中,需要将字符对应的码值(整数)找到
- 存储:找到汉字对应的码值,转成二进制,存储
- 读取:二进制转成码值,通过码值到
utf8对照表中找到对应的字符,读取
-
字符和码值的对应关系是通过字符编码表决定的(规定死的)
-
Go语言的编码都统一成了
utf-8,非常的方便,很统一,再也没有编码乱码的问题
5. 字符串类型
5.1 字符串的概念
Go语言中的字符串以原生数据类型出现,使用字符串就像使用其他原生数据类型 int、bool、float32、float64 等 一样。 Go 语言里的字符串的内部实现使用UTF-8编码。 字符串的值为双引号"中的内容,可以在Go语言的源码中直接添加非ASCII码字符,例如:
s1 := "hello"
s2 := "你好"
字符串就是一串固定长度的字符连接起来的字符序列,Go的字符串是由单个字节链接起来的,Go语言的字符串的编码使用UTF-8编码表示Unicode文本
func main() {
var address string = "背景你好"
fmt.Println(address)
}
5.2 字符串转义符
| 转义 | 含义 |
|---|---|
| \r | 回车符(返回行首) |
| \n | 换行符(直接跳到下一行的同列位置) |
| \t | 制表符 |
| ' | 单引号 |
| " | 双引号 |
| \ | 反斜杠 |
func main() {
// 打印路径,用\转义
fmt.Println("str := \"c:\\pprof\\main.exe\"")
}
5.3 多行字符串
Go语言中要定义一个多行字符串时,就必须使用反引号字符:
func main() {
s1 := `你好啊
我不好
`
fmt.Println(s1)
}
反引号间换行将被作为字符串中的换行,但是所有的转义字符均无效,文本将会原样输出。
5.4 字符串常用操作方法
5.4.1 求长度(字节数)
中文占3字节
func main() {
s1 := "小明"
fmt.Println(len(s1))
}
// 打印结果
6
5.4.2 遍历
// 未转成 []rune 切片时, 对于 北京 这两个中文, 底层是用字节来存储的
// 所以当遍历时, 北京 这两个中文可能是由 四个字符 来表示的, 无法真实的表示出 北京 这两个中文, 所以需要转成 []rune 切片
// for i
str1 := "hello北京"
newStr := []rune(str1) // 如果字符串中有中文可以将str1,转换成[]rune切片,否则会按照默认的字节遍历
for i := 0; i < len(newStr); i++ {
fmt.Printf("第 %v 个字符, 字符为 %c, ascii码值为 %v\n", i, newStr[i], newStr[i])
}
// for range
str1 := "hello北京"
for i, v := range str1 {
fmt.Printf("第 %v 个字符, 字符为 %c, ascii码值为 %v\n", i, v, v)
}
5.4.3 转整型
n,err := strconv.Atoi("12") // 转换不成功会有err 返回值,可以通过对err进行判断
5.4.4 整型转字符串
str := strconv.Itoa(123)
5.4.5 字符串转 byte 数组
bytes := []byte("hello go") // 转成字节
5.4.6 byte数组 转字符串:
str := string([]byte{97,98,99}) // 转成97,98,99对应的字符组成字符串
5.4.7 查询子串是否在字符串中
b := strings.Contains("hello","o") // 返回值为bool
5.4.8 统计指定子串个数
strings.Count("ceheese","e") // 没有返回0
5.4.9 不区分大小写的字符串比较
==是区分大小写的比较
strings.EqualFold("ab","AB") // 返回值为bool
5.4.10 返回子串在字符串中第一次出现的index值
如果没有返回-1
strings.index("abcaa","a")
5.4.11 字符串替换
strings.Replace("go go hello","go","go语言",n) // n可以指定替换几个,如果n=-1, 表示全部替换
5.4.12 大小写转换
strings.Tolower("Go")
strings.ToUpper("go")
5.4.13 去除字符串两边的空格
strings.TrimSpace(" hello ")
5.4.14 字符串两边,指定字符去除
strings.Trim("!hello!","!")
5.4.15 字符串左边指定字符去除
strings.TrimLeft("!hello","!")
5.4.16 字符串右边指定字符去除
strings.TrimRight("!hello!","!")
5.4.17 是否以指定字符开头
strings.HasPrefix("http://","http")
5.4.18 是否以指定字符结束
strings.HasSuffix("http://www.baidu.com","com")
5.4.19 拼接字符串
用+ 拼接
func main() {
s1 := "小明"
s2 := "啊"
fmt.Println(s1 + s2)
}
// 打印结果
小明啊
fmt.Sprintf()
func main() {
s1 := "小明"
s2 := "啊"
fmt.Println(fmt.Sprintf("%v%v",s1,s2))
}
// 打印结果
小明啊
5.4.20 分割
func main() {
var s1 string = "小明a啊"
fmt.Println(strings.Split(s1,"a"))
}
// 打印结果
[小明 啊]
5.4.21 索引取值
func main() {
var s1 string = "小明a啊a"
fmt.Println(s1[0])
fmt.Println(s1[0:3])
}
// 打印结果
229
小
5.4.22 join
func main() {
var a = []string{"a","b","c"}
fmt.Println(strings.Join(a,"_"))
}
// 打印结果
a_b_c
5.4.23 修改子串
要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。
func main() {
// 转成 []rune
s1 := "小明啊"
rs1 := []rune(s1)
rs1[0] = '又'
s1 = string(rs1)
fmt.Println(s1)
// 转成 []byte
s2 := "Hello"
rs2 := []byte(s2)
rs2[0] = 'J'
s2 = string(rs2)
fmt.Println(s2)
}
// 打印结果
又明啊
Jello
5.5 注意事项
-
Go语言的字符串的字节使用
UTF-8编码表示Unicode文本,乱码问题不会再成为困扰 -
字符串一旦赋值,字符串就不能修改了,在Go中字符串是不可变的
var address string = "背景你好" // address[0] = "我不好" // 不可改变字符串中的某个元素 address = "我不好" // 可以重新赋值 fmt.Println(address,unsafe.Sizeof(address)) -
字符串的表示方法有两种
- 双引号,会识别
\这种转义字符 - 反引号,以字符串的原生形式输出,包括换行和特殊字符,可以实现防止共计,或者输出源代码等效果
- 双引号,会识别
-
字符串拼接方式
var address string = "北京你好" var age string = "18" var address_age = address + age fmt.Println(address_age) address += age fmt.Println(address) -
当字符串的长度太长是,需要使用到多行字符串,注意需要将+保留在上一行,因为编译器会自动加分号
不保留在上一行,会表示这一行代码结束了,下一行代码就会有错var address string = "背景你好" + "今天" // var address string = "背景你好" // + "今天" // 错误!!! + 号要留在上一行 fmt.Println(address)
6. 基本数据类型的默认值
在Go中,数据类型都有一个默认值,当没有赋值时,就会保留其默认值,在Go中的默认值又叫做零值

7. 基本数据类型的转换
Go在不同类型的变量之间赋值时需要显示转换(强制转换),也就是说golang中数据类型不能自动转换
1. 语法格式
T(v)
// 将值v转换为类型T
// T:就是数据类型,比如int32,int64,float32等等
// v:就是需要转换的变量
1. int 和 float 的 转换
func main(){
// int转成int32
var str_num int = 1
int_num := int32(str_num)
// float64转成float32
var float_num = 3.125
var new_float_num float32 = float32(float_num)
// int转成float64
var str_num int = 1
int_num := float64(str_num)
}
2. string的转换
在程序开发中,经常需要将基本数据类型转换成string类型,或者将string类型转成基本数据类型
2.1 fmt.Sprint
func main() {
var str1_num int = 1000
var str string // 空的字符串
str = fmt.Sprintf("%d", str1_num) //字符串拼接
fmt.Printf("str1_num 转换后的 type (%T) is %q\n", str, str)
}
2.2 strconv包的函数
// 将整型转成任意进制的字符串
strconv.FormatInt(int64(str1_num),2)
// 将整型转成十进制的字符串
// 底层调用FormatInt(str_num,10)
strconv.Itoa(str_num)
package main
import (
"fmt"
"strconv"
)
func main() {
var str1_num int = 1000
var str2_num float64 = 154.24554
var str3_num bool = true
var str4_num int = 123
var str4_num int64 = 456
var str string // 空的字符串
// 参数1类型为int64,参数2表示进制
str = strconv.FormatInt(int64(str1_num),2)
fmt.Printf("str1_num(%T) 转换后为 %q\n",str,str)
str = strconv.FormatFloat(str2_num,'f',10,64) // float转成10位的float64的字符串
fmt.Printf("str1_num(%T) 转换后为 %q\n",str,str)
str = strconv.FormatBool(str3_num) // bool 转成 字符串
fmt.Printf("str1_num(%T) 转换后为 %q\n",str,str)
str = strconv.Itoa(str4_num) // int类型很方便的转换成字符串
fmt.Printf("str (%T) 转换后为%q",str,str)
str = strconv.Itoa(int(str5_num)) // int64必须转成int,才可以用这个函数
fmt.Printf("str (%T) 转换后为%q",str,str)
}
2.3 string转成基本数据类型
package main
import (
"fmt"
"strconv"
)
func main() {
var str1 string = "true"
var str_to_bool bool
str_to_bool , _ = strconv.ParseBool(str1)
fmt.Printf("str_to_bool (%T) 转换成%q\n",str_to_bool,str_to_bool)
var str2 string = "123456"
var str_to_int int64
var str_to_int2 int
str_to_int , _ = strconv.ParseInt(str2,10,64) // 只能转成int64,如果是int需要强转
str_to_int2 = int(str_to_int)
fmt.Printf("str_to_bool (%T) 转换成%v\n",str_to_int2,str_to_int2)
var str3 string = "12.1254"
var str_to_float float64
str_to_float , _ = strconv.ParseFloat(str3,64)
fmt.Printf("str_to_float (%T) 转换成%v",str_to_float,str_to_float)
}
说明: 因为返回的是int64或者float64,如果希望得到int32或float32,用int32()/float32()强转一下
3. 注意事项
-
Go中,数据类型的转换可以是表示范围小转为表示范围大,表示范围大转为表示范围小
-
转换过程为重新开辟空间并定义类型,不会改变原来的变量的类型
-
在转换中,比如将int64转成int8,编译时不会报错,只是转换的结果是按溢出处理(得到一个和希望结果不一样的值)
var n1 int32 = 12 n4 := int8(n1) + 127 fmt.Println(n4) // 结果为-117 -
不同的数据类型运算时需要强制转换后再运算
var a int32 = 10 var b int64 = 32 // 不同的数据类型运算时,要强制转换后再运算 fmt.Println(int64(a) + b) -
在将string类型转换成基本数据类型时,要确保string类型能够转成有效的数据,比如可以吧
"123"转成一个整数,但是不能把"hello"转成一个整数,如果这样做,Golang直接将其转换成0,其他所有转不成功的数据类型都会置其为默认值

浙公网安备 33010602011771号