前言
一个程序就是一个世界,不论是使用哪种高级程序语言编写程序, 变量都是其程序的基本组成单位,
变量
在 go 中 变量是用于存储数据的命名空间(内存位置),它可以表示一个值,这个值在程序执行过程中可能会发生改变。- +-------------+ +---------------------+
- | 变量名: myVar|------>| 内存地址: 0x12345678|
- +-------------+ +---------------------+
- | 数据值: 42 |
- +---------------------+
复制代码 关键概念
- 标识符(名称): 变量具有一个唯一的名称,用于在程序中引用它。变量名应遵循编程语言的命名规则,通常以字母、数字和下划线组成,并且不能以数字开头。关键字和预定义标识符可以查看附录 :附录
- 数据类型: 变量有一个与之关联的数据类型,如整数、浮点数、布尔值或自定义类型。数据类型决定了变量可以存储的值的范围和类型。
- 值: 变量表示一个值,这个值可以在程序执行过程中改变。通过赋值操作,我们可以将一个新值存储到变量中。
- 作用域: 变量在程序中的可见范围称为作用域。作用域决定了在哪些部分的代码中可以访问和修改变量。通常,局部变量在函数或代码块内部定义,全局变量在整个程序范围内定义。
- 生命周期: 变量的生命周期是从创建到销毁的过程。局部变量的生命周期通常与函数或代码块的执行周期相同;全局变量的生命周期从程序启动到程序结束。
变量的使用
- go 中 局部变量的声明方式有 4种
- go 中 全局变量的声明方式有 2 种
示例
- package main
- import "fmt"
- // 全局变量
- var globalInt = 100
- var globalFloat = 9.7
- // 一次性声明多个全局变量
- var (
- globalInt2 = 500
- globalString2 = "netty"
- )
- func main() {
- // 局部变量
- // 1. 变量声明
- var age int
- // 2. 变量赋值
- age = 18
- // 3. 变量使用
- fmt.Println("age =", age)
- // 2、声明和赋值可以合并成一句
- var age2 int = 19
- fmt.Println("age2 =", age2)
- // 以下代码将会报错,因为变量 age 重复声明
- // var age int = 20
- // fmt.Println("age =", age)
- // 以下代码将会报错,因为浮点数不能直接赋值给整数类型变量
- // var num int = 12.56
- // fmt.Println("num =", num)
- // 指定变量类型,使用默认值
- var age3 int
- fmt.Println(age2)
- // 3、自动类型推断
- var name = "tom"
- fmt.Println(name)
- //4、 省略 var 关键字,使用 :=
- gender := "男"
- fmt.Println(gender)
- // 一次性声明多个局部变量
- var n1, n2, n3 int
- fmt.Println(n1)
- fmt.Println(n2)
- fmt.Println(n3)
- // 一次性声明多个局部变量并赋值
- var n4, name2, n5 = 10, "jack", 7.8
- fmt.Println(n4)
- fmt.Println(name2)
- fmt.Println(n5)
- // 使用 := 一次性声明多个局部变量并赋值
- n6, height := 6.9, 100.6
- fmt.Println(n6)
- fmt.Println(height)
- // 输出全局变量
- fmt.Println(globalInt)
- fmt.Println(globalFloat)
- fmt.Println(globalInt2)
- fmt.Println(globalString2)
- }
复制代码 数据类型
Golang变量的数据类型包含基本数据类型和派生(复杂)数据类型:
类别数据类型说明基本数据类型bool布尔类型,值为 true 或 falseint8, int16, int32, int64有符号整数类型,分别占用 8, 16, 32, 64 位存储空间uint8, uint16, uint32, uint64无符号整数类型,分别占用 8, 16, 32, 64 位存储空间int有符号整数类型,大小与操作系统位数相关(32 位或 64 位)uint无符号整数类型,大小与操作系统位数相关(32 位或 64 位)uintptr无符号整数类型,足以存储指针的大小float32, float64浮点数类型,分别占用 32 位和 64 位存储空间complex64, complex128复数类型,分别占用 64 位和 128 位存储空间byte字节类型,等同于 uint8runeUnicode 字符类型,等同于 int32string字符串类型派生数据类型array固定长度的数组类型slice可变长度的数组类型(切片)map无序键值对集合(字典)struct自定义数据结构(结构体)interface定义一组方法的集合(接口)pointer存储变量内存地址的类型(指针)channel用于协程间通信的类型(通道)function函数类型整数类型
简单的说,就是用于存放整数值的,比如10,-45,6712等等。
有符号整数类型:
类型是否有符号占用空间取值范围int8是8 位 (1 字节)-128 到 127 (-2^7 到 2^7-1)int16是16 位 (2 字节)-32,768 到 32,767 (-2^15 到 2^15-1)int32是32 位 (4 字节)-2,147,483,648 到 2,147,483,647 (-2^31 到 2^31-1)int64是64 位 (8 字节)-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 (-2^63 到 2^63-1)PS:127怎么算出来的?
- 01111111 –>二进制 —》转为十进制:
- 1*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0
- = 64 + 32 + 16 + 8 + 4 + 2 + 1
- = 127
复制代码 PS:-128怎么算出来的?
- 10000000 —>二进制 —>一看就是个负数
- 10000000 –》负数的二进制
- 减1:01111111
- 取反:10000000 —》得到一个正数 2^7 = 128
- 加负号:-128
复制代码 无符号整数类型:
这些类型可用于表示不同范围的非负整数值。
类型是否有符号占用空间取值范围uint8否8 位 (1 字节)0 到 255 (0 到 2^8-1)uint16否16 位 (2 字节)0 到 65,535 (0 到 2^16-1)uint32否32 位 (4 字节)0 到 4,294,967,295 (0 到 2^32-1)uint64否64 位 (8 字节)0 到 18,446,744,073,709,551,615 (0 到 2^64-1)表数范围的边界计算:- 11111111= 2^7+127 = 128 + 127 = 255
- 00000000 = 0
复制代码 其他整数类型
以下是一个完整的表格,将取值范围放在同一个单元格中:
类型是否有符号占用空间取值范围说明int是32 位或64 位 (依赖操作系统)32 位: -2^31 到 2^31-1
64 位: -2^63 到 2^63-1有符号整数,大小与操作系统位数相关uint否32 位或64 位 (依赖操作系统)32 位: 0 到 2^32-1
64 位: 0 到 2^64-1无符号整数,大小与操作系统位数相关uintptr否32 位或64 位 (依赖操作系统)32 位: 0 到 2^32-1
64 位: 0 到 2^64-1无符号整数,足以存储指针的大小byte否8 位 (1 字节)0 到 2^8-1字节类型,等同于 uint8rune是32 位 (4 字节)-2^31 到 2^31-1Unicode 字符类型,等同于 int32这些类型在特定场景下(如操作系统相关编程、处理字节和 Unicode 字符)非常有用。
PS:Golang的整数类型,默认声明为int类型
查询变量占用的字节数
在 Go 语言中,可以使用 unsafe.Sizeof() 函数来查看变量占用的字节数。unsafe.Sizeof() 函数返回一个变量所占用的字节数,以 uintptr 类型表示。请注意,使用 unsafe 包可能会带来潜在的安全风险和跨平台兼容性问题,因此在使用时要谨慎。- package main
- import (
- "fmt"
- "unsafe"
- )
- func main() {
- var a int32 = 10
- var b float64 = 20.5
- var c bool = true
- var d byte = 255
- var e rune = 'A'
- var f string = "hello"
- fmt.Printf("Size of int32: %d bytes\\n", unsafe.Sizeof(a))
- fmt.Printf("Size of float64: %d bytes\\n", unsafe.Sizeof(b))
- fmt.Printf("Size of bool: %d bytes\\n", unsafe.Sizeof(c))
- fmt.Printf("Size of byte: %d bytes\\n", unsafe.Sizeof(d))
- fmt.Printf("Size of rune: %d bytes\\n", unsafe.Sizeof(e))
- fmt.Printf("Size of string: %d bytes\\n", unsafe.Sizeof(f))
- }
复制代码 在这个示例中,我们使用 unsafe.Sizeof() 函数查看了不同类型变量占用的字节数,并将结果打印到控制台。请注意,对于 string 类型,unsafe.Sizeof() 函数返回的值是字符串头部的大小,而不是实际字符串内容的大小。要获取字符串内容的长度,可以使用 len() 函数。
这么多整数类型,使用的时候该如何选择呢?
Golang程序中整型变量在使用时,遵守保小不保大的原则,
即:在保证程序正确运行下,尽量使用占用空间小的数据类型
浮点类型
浮点类型介绍:
简单的说,就是用于存放小数值的,比如3.14、0.28、-7.19等等。
浮点类型种类:
类型是否有符号占用空间取值范围及精度说明float32是32 位 (4 字节)1.18e-38 到 3.4e38(约 7 位有效数字)单精度浮点数float64是64 位 (8 字节)2.23e-308 到 1.8e308(约 16 位有效数字)双精度浮点数(通常使用)在大多数情况下,推荐使用 float64 类型,因为它具有更高的精度和更广泛的取值范围。
PS:底层存储空间和操作系统无关
PS:浮点类型底层存储:符号位+指数位+尾数位,所以尾数位只是存了 一个大概,很可能会出现精度的损失。
示例:
- package main
- import "fmt"
- func main() {
- // 定义正的 float32 类型变量
- var num1 float32 = 3.14
- fmt.Println(num1)
- // 定义负的 float32 类型变量
- var num2 float32 = -3.14
- fmt.Println(num2)
- // 使用科学计数法表示的 float32 类型变量
- var num3 float32 = 314e-2
- fmt.Println(num3)
- // 使用科学计数法表示的 float32 类型变量
- var num4 float32 = 314e+2
- fmt.Println(num4)
- // 使用科学计数法表示的 float32 类型变量
- var num5 float32 = 314e+2
- fmt.Println(num5)
- // 使用科学计数法表示的 float64 类型变量
- var num6 float64 = 314e+2
- fmt.Println(num6)
- // float32 类型变量可能存在精度损失
- var num7 float32 = 256.000000916
- fmt.Println(num7)
- // float64 类型变量具有更高的精度
- var num8 float64 = 256.000000916
- fmt.Println(num8)
- // Go 语言中默认的浮点类型为 float64
- var num9 = 3.17
- fmt.Printf("num9对应的默认的类型为:%T", num9)
- }
复制代码 字符类型
示例:
- package main
- import "fmt"
- func main() {
- // 定义 ASCII 字符类型的数据 (byte 类型)
- var char1 byte = 'a'
- fmt.Println(char1) // 输出: 97
- var char2 byte = '6'
- fmt.Println(char2) // 输出: 54
- var char3 byte = '('
- fmt.Println(char3 + 20) // 输出: 40
- // 字符类型本质上是一个整数,可以直接参与运算。输出时,会将对应的码值输出。
- // 字母、数字、标点等字符在底层按照 ASCII 进行存储。
- // 定义 Unicode 字符类型的数据 (int 类型)
- var char4 int = '中'
- fmt.Println(char4) // 输出: 20013
- // 汉字字符在底层对应的是 Unicode 码值。
- // 码值为 20013,超出 byte 类型能存储的范围,因此使用 int 类型存储。
- // 总结:Go 语言的字符使用 UTF-8 编码(Unicode 是对应的字符集,UTF-8 是 Unicode 的其中一种编码方案)。
- var char5 byte = 'A'
- // 若要显示对应的字符,必须采用格式化输出
- fmt.Printf("char5 对应的具体的字符为:%c", char5) // 输出: A
- }
复制代码 转义字符
转义字符定义作用\\反斜杠表示一个反斜杠字符\'单引号表示一个单引号字符\"双引号表示一个双引号字符\n换行符在输出中插入一个换行符\r回车符在输出中插入一个回车符,使光标移动到行首\t制表符(水平制表符)在输出中插入一个制表符,用于对齐文本\b退格符在输出中插入一个退格符,使光标回退一个字符位置\f换页符在输出中插入一个换页符,使光标移动到下一页\v垂直制表符在输出中插入一个垂直制表符,用于垂直对齐文本\ooo八进制编码字符表示一个八进制编码的字符\xhh十六进制编码字符表示一个十六进制编码的字符\uhhhhUnicode 编码字符表示一个 Unicode 编码的字符(16 位)\UhhhhhhhhUnicode 编码字符表示一个 Unicode 编码的字符(32 位)示例
- package main
- import "fmt"
- func main() {
- // 演示转义字符的用法
- // \n 换行
- fmt.Println("aaa\nbbb")
- // \b 退格
- fmt.Println("aaa\bbbb")
- // \r 回车:光标回到本行的开头,后续输入会替换原有的字符
- fmt.Println("aaaaa\rbbb")
- // \t 制表符:水平制表符,用于对齐文本
- fmt.Println("aaaaaaaaaaaaa")
- fmt.Println("aaaaa\tbbbbb")
- fmt.Println("aaaaaaaa\tbbbbb")
- // " 双引号:表示一个双引号字符
- fmt.Println(""Golang"")
- }
复制代码 布尔类型
- 布尔类型也叫bool类型,bool类型数据只允许取值true和false
- 布尔类型占1个字节。
- 布尔类型适于逻辑运算,一般用于程序流程控制
- package main
- import "fmt"
- func main() {
- // 测试布尔类型的数值
- var flag1 bool = true
- fmt.Println(flag1) // 输出: true
- var flag2 bool = false
- fmt.Println(flag2) // 输出: false
- var flag3 bool = 5 < 9
- fmt.Println(flag3) // 输出: true
- }
复制代码 字符串类型
字符串就是一串固定长度的字符连接起来的字符序列。
字符串示例
- package main
- import "fmt"
- func main() {
- // 1. 定义一个字符串
- var s1 string = "全面拥抱Golang"
- fmt.Println(s1)
- // 2. 字符串是不可变的:指的是字符串一旦定义好,其中的字符的值不能改变
- var s2 string = "abc"
- // s2 = "def"
- // s2[0] = 't'
- fmt.Println(s2)
- // 3. 字符串的表示形式
- // (1) 如果字符串中没有特殊字符,字符串的表示形式用双引号
- // var s3 string = "asdfasdfasdf"
- // (2) 如果字符串中有特殊字符,字符串的表示形式用反引号 ``
- var s4 string = `
- package main
- import "fmt"
- func main(){
- //测试布尔类型的数值:
- var flag01 bool = true
- fmt.Println(flag01)
- var flag02 bool = false
- fmt.Println(flag02)
- var flag03 bool = 5 < 9
- fmt.Println(flag03)
- }`
- fmt.Println(s4)
- // 4. 字符串的拼接效果
- var s5 string = "abc" + "def"
- s5 += "hijk"
- fmt.Println(s5)
- // 当一个字符串过长的时候:注意:+ 保留在上一行的最后
- var s6 string = "abc" + "def" + "abc" + "def" + "abc" + "def" +
- "abc" + "def" + "abc" + "def" + "abc" + "def" + "abc" + "def" +
- "abc" + "def" + "abc" + "def" + "abc" + "def" + "abc" + "def" +
- "abc" + "def" + "abc" + "def" + "abc" + "def" + "abc" + "def"
- fmt.Println(s6)
- }
复制代码 基本数据类型的默认值
在Golang中数据类型都有一个默认值,当程序员没有赋值时,就会保留默认值(默认值又叫零值)。
以下是一个表格,展示了 Go 语言中各种数据类型的默认值:
数据类型默认值说明int0整数类型默认值uint0无符号整数类型默认值float320.0单精度浮点数默认值float640.0双精度浮点数默认值boolfalse布尔类型默认值string""空字符串默认值array元素的默认值数组元素类型的默认值slicenil切片类型默认值mapnil映射类型默认值pointernil指针类型默认值functionnil函数类型默认值channelnil通道类型默认值struct结构体字段的默认值结构体中各字段类型的默认值这个表格包含了 Go 语言中各种数据类型的默认值。当声明一个变量而不指定初始值时,变量会被赋予其数据类型的默认值。例如,整数类型的默认值是 0,布尔类型的默认值是 false,字符串类型的默认值是空字符串("")。对于复合数据类型(如数组、切片、映射、结构体等),它们的默认值取决于其元素或字段的数据类型。
基本数据类型之间的转换
Go在不同类型的变量之间赋值时需要显式转换,并且只有显式转换(强制转换)。
语法:
表达式T(v)将值v转换为类型T
类型转换示例
- package main
- import "fmt"
- func main() {
- // 类型转换示例
- // 声明一个 int 类型变量
- var num1 int = 100
- fmt.Println(num1)
- // 将 int 类型转换为 float32 类型
- var num2 float32 = float32(num1)
- fmt.Println(num2)
- // 注意:num1 的类型仍然是 int,只是将 num1 的值 100 转换为了 float32 类型
- fmt.Printf("%T\n", num1) // 输出: int
- // 将 int64 类型转换为 int8 类型时,可能会发生数据溢出
- var num3 int64 = 888888
- var num4 int8 = int8(num3)
- fmt.Println(num4) // 输出: 56
- // 将 int32 类型转换为 int64 类型,并进行数值运算
- var num5 int32 = 12
- var num6 int64 = int64(num5) + 30
- fmt.Println(num5)
- fmt.Println(num6)
- // 将 int64 类型转换为 int8 类型时,可能会发生数据溢出
- var num7 int64 = 12
- var num8 int8 = int8(num7) + 127
- // 编译通过,但结果可能会溢出
- fmt.Println(num8) // 输出: -117
- // 将 int64 类型转换为 int8 类型时,可能会发生数据溢出
- // var num9 int8 = int8(num7) + 128 // 编译不会通过,因为 128 超出了 int8 的取值范围
- }
复制代码 基本数据类型转为string
在程序开发中,我们经常需要将基本数据类型转成string类型。或者将string类型转成基本数据类型。
方式1:mt.Sprintf(“%参数”,表达式) 推荐方式
- package main
- import (
- "fmt"
- )
- func main() {
- // 将 int 类型转换为 string 类型
- num1 := 42
- str1 := fmt.Sprintf("%d", num1)
- fmt.Printf("str1: %s, type: %T\n", str1, str1)
- // 将 float64 类型转换为 string 类型
- num2 := 3.14159
- str2 := fmt.Sprintf("%.2f", num2)
- fmt.Printf("str2: %s, type: %T\n", str2, str2)
- // 将 bool 类型转换为 string 类型
- flag := true
- str3 := fmt.Sprintf("%t", flag)
- fmt.Printf("str3: %s, type: %T\n", str3, str3)
- }
复制代码 按使用频率排序的 fmt.Printf() 占位符:
占位符说明示例%v默认格式输出,根据变量的类型自动选择输出格式fmt.Printf("%v", x)%s输出字符串fmt.Printf("%s", x)%d输出十进制整数fmt.Printf("%d", x)%f输出浮点数,不使用科学计数法fmt.Printf("%f", x)%T输出变量的类型fmt.Printf("%T", x)%t输出布尔值fmt.Printf("%t", x)%x输出十六进制整数,使用小写字母fmt.Printf("%x", x)%X输出十六进制整数,使用大写字母fmt.Printf("%X", x)%b输出整数的二进制表示fmt.Printf("%b", x)%e输出科学计数法表示的浮点数,使用小写字母 efmt.Printf("%e", x)%E输出科学计数法表示的浮点数,使用大写字母 Efmt.Printf("%E", x)%g输出浮点数,根据数值大小自动选择使用 %f 或 %e 格式fmt.Printf("%g", x)%G输出浮点数,根据数值大小自动选择使用 %f 或 %E 格式fmt.Printf("%G", x)%p输出指针的十六进制表示fmt.Printf("%p", x)%c输出整数对应的 Unicode 字符fmt.Printf("%c", x)%o输出八进制整数fmt.Printf("%o", x)%q输出带引号的字符串或字符,对于字符串,输出双引号;对于字符,输出单引号fmt.Printf("%q", x)%U输出 Unicode 码点表示的字符串fmt.Printf("%U", x)%+v输出结构体时,包含字段名fmt.Printf("%+v", x)%#v输出 Go 语言语法格式的值fmt.Printf("%#v", x)%%输出一个百分号(%)fmt.Printf("%%")%n输出已写入的字节数(n 为 int 类型的指针)fmt.Printf("%n", &x)方式2:使用strconv包的函数
- package main
- import (
- "fmt"
- "strconv"
- )
- func main() {
- // 将 int 类型转换为 string 类型
- num1 := 42
- str1 := strconv.Itoa(num1)
- fmt.Printf("str1: %s, type: %T\n", str1, str1)
- // 将 float64 类型转换为 string 类型
- num2 := 3.14159
- str2 := strconv.FormatFloat(num2, 'f', 2, 64)
- fmt.Printf("str2: %s, type: %T\n", str2, str2)
- // 将 bool 类型转换为 string 类型
- flag := true
- str3 := strconv.FormatBool(flag)
- fmt.Printf("str3: %s, type: %T\n", str3, str3)
- // 将 int64 类型转换为 string 类型
- num3 := int64(123456789)
- str4 := strconv.FormatInt(num3, 10)
- fmt.Printf("str4: %s, type: %T\n", str4, str4)
- // 将 uint64 类型转换为 string 类型
- num4 := uint64(987654321)
- str5 := strconv.FormatUint(num4, 10)
- fmt.Printf("str5: %s, type: %T\n", str5, str5)
- }
复制代码 两者差异
fmt.Sprintf() 和 strconv 包中的函数之间的主要区别在于性能和灵活性:
- 性能: strconv 包中的函数通常比 fmt.Sprintf() 更快,因为它们专门针对特定的数据类型进行了优化。fmt.Sprintf() 是一个通用的格式化字符串函数,因此它需要处理更多的类型和格式选项,这可能会导致性能略低于 strconv 包中的函数。
- 灵活性: fmt.Sprintf() 提供了更多的格式选项和控制,可以轻松地处理多种数据类型和格式。而 strconv 包中的函数是专门针对特定数据类型的,因此在某些情况下可能不如 fmt.Sprintf() 灵活。
根据实际需求和性能要求,可以选择使用 fmt.Sprintf() 或 strconv 包中的函数进行数据类型转换。在对性能要求不高的情况下,使用 fmt.Sprintf() 可能更方便和简单。在对性能要求较高的情况下,可以考虑使用 strconv 包中的函数。
string转为基本数据类型
- package main
- import (
- "fmt"
- "strconv"
- )
- func main() {
- // 将 string 类型转换为 int 类型
- str1 := "42"
- num1, err1 := strconv.Atoi(str1)
- if err1 != nil {
- fmt.Println("Error:", err1)
- } else {
- fmt.Printf("num1: %d, type: %T\n", num1, num1)
- }
- // 将 string 类型转换为 float64 类型
- str2 := "3.14159"
- num2, err2 := strconv.ParseFloat(str2, 64)
- if err2 != nil {
- fmt.Println("Error:", err2)
- } else {
- fmt.Printf("num2: %f, type: %T\n", num2, num2)
- }
- // 将 string 类型转换为 bool 类型
- str3 := "true"
- flag, err3 := strconv.ParseBool(str3)
- if err3 != nil {
- fmt.Println("Error:", err3)
- } else {
- fmt.Printf("flag: %t, type: %T\n", flag, flag)
- }
- // 将 string 类型转换为 int64 类型
- str4 := "123456789"
- num3, err4 := strconv.ParseInt(str4, 10, 64)
- if err4 != nil {
- fmt.Println("Error:", err4)
- } else {
- fmt.Printf("num3: %d, type: %T\n", num3, num3)
- }
- // 将 string 类型转换为 uint64 类型
- str5 := "987654321"
- num4, err5 := strconv.ParseUint(str5, 10, 64)
- if err5 != nil {
- fmt.Println("Error:", err5)
- } else {
- fmt.Printf("num4: %d, type: %T\n", num4, num4)
- }
- }
复制代码 指针
- package main
- import "fmt"
- func main() {
- // 声明一个整数变量 num
- num := 42
- fmt.Println("num:", num)
- // 声明一个指针变量 ptr
- var ptr *int
- // 将 num 的地址赋值给 ptr
- ptr = &num
- fmt.Println("ptr points to:", *ptr)
- // 通过 ptr 访问 num 的值
- fmt.Println("Value of num through ptr:", *ptr)
- // 通过 ptr 修改 num 的值
- *ptr = 100
- fmt.Println("New value of num:", num)
- }
复制代码 sequenceDiagram participant main participant num participant ptr main->>num: 声明整数变量 num Note over main,num: int num = 42 main->>ptr: 声明指针变量 ptr Note over main,ptr: int *ptr main->>ptr: 将 num 的地址赋值给 ptr Note over main,ptr: ptr = &num main->>ptr: 通过 ptr 访问 num 的值 Note over main,ptr: *ptr main->>ptr: 通过 ptr 修改 num 的值 Note over main,ptr: *ptr = 100指针细节
- 指针变量的地址不可以不匹配:不能指向不同数据类型
- 基本数据类型(又叫值类型),都有对应的指针类型,形式为*数据类型,比如int的对应的指针就是*int, float32对应的指针类型就是*float32。依次类推。
附录
关键字和预定义标识符
关键字是 Go 语言中具有特殊含义的单词,用于控制语言结构。预定义标识符是 Go 语言中预先声明的常量、类型、函数等。在命名变量、函数或类型时,应避免使用这些关键字和预定义标识符。
关键字就是程序发明者规定的有特殊含义的单词,又叫保留字。
关键字:
go语言中一共有25个关键字。
关键字说明break跳出循环或 switch 语句defaultswitch 语句的默认分支func声明函数或方法interface声明接口类型select用于从多个通道中接收数据caseswitch 语句的每个分支defer延迟执行函数,直到包含该 defer 语句的函数执行完毕go以并发方式运行函数map声明映射类型struct声明结构体类型chan声明通道类型elseif 语句的其他分支goto无条件跳转到指定标签位置package声明包名switch多分支选择语句const声明常量fallthrough使 switch 语句继续执行下一个 case 分支,而不是跳出 switch 语句if条件判断语句range用于遍历数组、切片、字符串或映射的元素type声明自定义类型continue跳过当前循环的剩余部分,进入下一次循环for循环语句import导入外部包return从函数返回var声明变量Go 语言的 36 个预定义标识符
基本数据类型:
预定义标识符说明bool布尔类型byte字节类型,等同于 uint8complex6464 位复数类型complex128128 位复数类型error错误接口float32单精度浮点数类型float64双精度浮点数类型int有符号整数类型int88 位有符号整数类型int1616 位有符号整数类型int3232 位有符号整数类型int6464 位有符号整数类型rune字符类型,等同于 int32string字符串类型uint无符号整数类型uint88 位无符号整数类型uint1616 位无符号整数类型uint3232 位无符号整数类型uint6464 位无符号整数类型uintptr无符号整数指针类型系统内置函数:
预定义标识符说明make分配内存并初始化切片、映射或通道new分配内存并初始化变量panic引发运行时恐慌recover从运行时恐慌中恢复print打印参数列表println打印参数列表并换行预定义常量:
预定义标识符说明true布尔类型的真值false布尔类型的假值iota用于常量计数器的特殊常量nil零值指针这些表格包含了 Go 语言的预定义标识符,包括基本数据类型、系统内置函数和预定义常量。在命名变量、函数或类型时,应避免使用这些预定义标识符。
扩展:进制和进制转换
在 Go 语言中,可以使用不同的进制表示整数,如二进制、八进制、十进制和十六进制。以下是各种进制表示的整数的示例:
- 二进制:以 0b 或 0B 开头,后跟二进制数字(0 和 1)。例如:0b1010 或 0B1010 表示十进制数 10。
- 八进制:以 0 开头,后跟八进制数字(0 到 7)。例如:012 表示十进制数 10。
- 十进制:直接写十进制数字(0 到 9)。例如:10 表示十进制数 10。
- 十六进制:以 0x 或 0X 开头,后跟十六进制数字(0 到 9,A 到 F 或 a 到 f)。例如:0xA 或 0Xa 表示十进制数 10。
进制转换
在 Go 语言中,可以使用 fmt.Printf() 或 strconv 包中的函数进行进制转换。以下是一些示例:- package main
- import (
- "fmt"
- "strconv"
- )
- func main() {
- num := 42
- // 十进制转二进制
- binStr := strconv.FormatInt(int64(num), 2)
- fmt.Printf("Decimal %d to binary: %s\n", num, binStr)
- // 十进制转八进制
- octStr := strconv.FormatInt(int64(num), 8)
- fmt.Printf("Decimal %d to octal: %s\n", num, octStr)
- // 十进制转十六进制
- hexStr := strconv.FormatInt(int64(num), 16)
- fmt.Printf("Decimal %d to hexadecimal: %s\n", num, hexStr)
- // 二进制转十进制
- binNum, _ := strconv.ParseInt("101010", 2, 0)
- fmt.Printf("Binary 101010 to decimal: %d\n", binNum)
- // 八进制转十进制
- octNum, _ := strconv.ParseInt("52", 8, 0)
- fmt.Printf("Octal 52 to decimal: %d\n", octNum)
- // 十六进制转十进制
- hexNum, _ := strconv.ParseInt("2A", 16, 0)
- fmt.Printf("Hexadecimal 2A to decimal: %d\n", hexNum)
- }
复制代码 在这个示例中,我们使用了 strconv.FormatInt() 和 strconv.ParseInt() 函数进行进制转换。这些函数可以根据需要将整数在不同进制之间进行转换。注意,strconv.ParseInt() 函数在转换过程中可能会发生错误(例如,无效的输入或溢出),因此需要检查返回的错误。
感谢阅读,如果觉得对你有帮助,就在右下角点个赞吧,感谢!合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |