Golang通脉之数据类型详情
来源:脚本之家
时间:2022-12-23 09:59:36 354浏览 收藏
本篇文章主要是结合我之前面试的各种经历和实战开发中遇到的问题解决经验整理的,希望这篇《Golang通脉之数据类型详情》对你有很大帮助!欢迎收藏,分享给更多的需要的朋友学习~
1、标识符与关键字
在了解数据类型之前,先了解一下go的标识符和关键字
1.1 标识符
在编程语言中标识符就是定义的具有某种意义的词,比如变量名、常量名、函数名等等。 Go语言中标识符允许由字母数字和_(下划线)组成,并且只能以字母和_开头:abc
, _
, _123
, a123
。
1.2 关键字
关键字是指语言预先定义好的具有特殊含义的标识符。 关键字和保留字都不建议用作变量名。
Go语言有25个关键字:
break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var
Go语言中有37个保留字
Constants: true false iota nil Types: int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr float32 float64 complex128 complex64 bool byte rune string error Functions: make len cap new append copy close delete complex real imag panic recover
2、变量
2.1 什么是变量
程序运行过程中的数据都是保存在内存中,想要在代码中操作某个数据时就需要去内存上找到这个变量,但是如果直接在代码中通过内存地址去操作变量的话,代码的可读性会非常差而且还容易出错,所以就利用变量将这个数据的内存地址保存起来,以后直接通过这个变量就能找到内存上对应的数据了。
所以变量的本质就是一小块内存,用于存储数据,在程序运行过程中数值可以改变
变量是为存储特定类型的值而提供给内存位置的名称。在go中声明变量有多种语法。
2.2 变量类型
变量(Variable
)的功能是存储数据。不同的变量保存的数据类型可能会不一样。常见变量的数据类型有:整型、浮点型、布尔型等。
Go语言中的每一个变量都有自己的类型,并且变量必须经过声明才能开始使用。
2.3 变量声明
Go语言中的变量需要声明后才能使用,同一作用域内不支持重复声明。 并且Go语言的变量声明后必须使用,否则无法通过编译。
标准声明:
Go语言的变量声明格式为:
var 变量名 变量类型
变量声明以关键字var开头,变量类型放在变量的后面,行尾无需分号:
var name string var age int var isTrue bool
批量声明:
每声明一个变量就需要写var
关键字会比较繁琐,go
语言中还支持批量变量声明:
var ( a string b int c bool d float32 )
变量的初始化:
Go语言在声明变量的时候,会自动对变量对应的内存区域进行初始化操作。每个变量会被初始化成其类型的默认值,即零值,例如: 整型和浮点型变量的默认值为0。 字符串变量的默认值为空字符串。 布尔型变量默认为false
。 切片、函数、指针变量的默认为nil
。
当然也可在声明变量的时候为其指定初始值。变量初始化的标准格式如下:
var 变量名 类型 = 表达式 var name string = "golang" var age int = 18
或者一次初始化多个变量
var name, age = "golang", 20
类型推导:
有时候会将变量的类型省略,这个时候编译器会根据等号右边的值来推导变量的类型完成初始化。
var name = "golang" var age = 18
短变量声明:
在函数内部,可以使用更简略的 :=
方式声明并初始化变量。
// 全局变量m var m = 100 func main() { n := 10 m := 200 // 此处声明局部变量m fmt.Println(m, n) }
匿名变量:
在使用多重赋值时,如果想要忽略某个值,可以使用匿名变量(anonymous variable
)。 匿名变量用一个下划线_表示,例如:
func foo() (int, string) { return 10, "golang" } func main() { x, _ := foo() _, y := foo() fmt.Println("x=", x) fmt.Println("y=", y) }
匿名变量不占用命名空间,不会分配内存,所以匿名变量之间不存在重复声明。
注意事项:
- 函数外的每个语句都必须以关键字开始(
var
、const
、func
等) :=
不能使用在函数外,不能定义全局变量,并且左边的变量名至少有一个是新的。- _多用于占位,表示忽略值。
- 变量必须先定义才能使用,定义了就一定要使用。
- 变量的类型和赋值的类型必须一致。
- 变量名在同一个作用于域内不能冲突。
3、常量
相对于变量,常量是恒定不变的值,多用于定义程序运行期间不会改变的那些值。 常量的声明和变量声明非常类似,只是把var换成了const
,常量在定义的时候必须赋值。
const pi = 3.1415 const e = 2.7182
声明了pi
和e
这两个常量之后,在整个程序运行期间它们的值都不能再发生变化了。
多个常量也可以一起声明:
const ( pi = 3.1415 e = 2.7182 )
const
同时声明多个常量时,如果省略了值则表示和上面一行的值相同。 例如:
const ( n1 = 100 n2 n3 )
上面示例中,常量n1
、n2
、n3
的值都是100。
常量可以作为枚举,常量组
const ( Unknown = 0 Female = 1 Male = 2 )
常量组中如不指定类型和初始化值,则与上一行非空常量右值相同
func main() { const ( x uint16 = 16 y s = "abc" z ) fmt.Printf("%T,%v\n", y, y) //uint16,16 fmt.Printf("%T,%v\n", z, z) //string,abc }
常量的注意事项:
- 常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型
- 不曾使用的常量,在编译的时候,是不会报错的
- 显示指定类型的时候,必须确保常量左右值类型一致,需要时可做显示类型转换。这与变量就不一样了,变量是可以是不同的类型值
3.1 iota
iota
是go语言的常量计数器,是特殊的常量,只能在常量的表达式中使用。
iota在const
关键字出现时将被重置为0
。const
中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。 使用iota能简化定义,在定义枚举时很有用。
const ( n1 = iota //0 n2 //1 n3 //2 n4 //3 )
几个常见的iota示例:
使用_
跳过某些值
const ( n1 = iota //0 n2 //1 _ n4 //3 )
iota
声明中间插队
const ( n1 = iota //0 n2 = 100 //100 n3 = iota //2 n4 //3 ) const n5 = iota //0
定义数量级 (这里的 多个 整型分为以下两个大类: 按长度分为: 其中,
表示左移操作,
1表示将1的二进制表示向左移10位,也就是由1变成了10000000000,也就是十进制的1024。同理2
const (
_ = iota
KB = 1
iota
定义在一行
const (
a, b = iota + 1, iota + 2 //iota = 0、a = 1, b = 2
c, d //iota = 1、c = 2, d = 3
e, f //iota = 2、e = 3, f = 4
)
Go
语言中有丰富的数据类型,除了基本的整型、浮点型、布尔型、字符串外,还有数组、切片、结构体、函数、map
、通道(channel
)等。4、基本数据类型
4.1 整型
int8
、int16
、int32
、int64
对应的无符号整型:uint8
、uint16
、uint32
、uint64
uint8
就是byte
型,int16
对应C语言中的short型,int64对应C语言中的long型。
特殊整型:类型
描述
uint8
无符号 8位整型 (0 到 255)
uint16
无符号 16位整型 (0 到 65535)
uint32
无符号 32位整型 (0 到 4294967295)
uint64
无符号 64位整型 (0 到 18446744073709551615)
int8
有符号 8位整型 (-128 到 127)
int16
有符号 16位整型 (-32768 到 32767)
int32
有符号 32位整型 (-2147483648 到 2147483647)
int64
有符号 64位整型 (-9223372036854775808 到 9223372036854775807)
类型 | 描述 |
---|---|
uint | 32位操作系统上就是uint32,64位操作系统上就是uint64 |
int | 32位操作系统上就是int32,64位操作系统上就是int64 |
uintptr | 无符号整型,用于存放一个指针 |
注意: 在使用int和 uint类型时,不能假定它是32位或64位的整型,而是考虑int和uint可能在不同平台上的差异。除非需要使用特定大小的整数,否则通常应该使用int来表示整数。 大小:32位系统32位,64位系统64位。 范围:-2147483648到2147483647的32位系统和-9223372036854775808到9223372036854775807的64位系统。
注意事项 获取对象的长度的内建len()函数返回的长度可以根据不同平台的字节长度进行变化。实际使用中,切片或 map 的元素数量等都可以用int来表示。在涉及到二进制传输、读写文件的结构描述时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用int和 uint。
数字字面量语法(Number literals syntax)
Go1.13版本之后引入了数字字面量语法,这样便于开发者以二进制、八进制或十六进制浮点数的格式定义数字,例如:
v := 0b00101101
, 代表二进制的 101101,相当于十进制的 45。 v := 0o377
,代表八进制的 377,相当于十进制的 255。 v := 0x1p-2,代表十六进制的 1 除以 2²,也就是 0.25。
而且还允许用 _ 来分隔数字,比如说: v := 123_456
表示 v 的值等于 123456
。
将一个整数以不同进制形式展示:
func main(){ // 十进制 var a int = 10 fmt.Printf("%d \n", a) // 10 fmt.Printf("%b \n", a) // 1010 占位符%b表示二进制 // 八进制 以0开头 var b int = 077 fmt.Printf("%o \n", b) // 77 // 十六进制 以0x开头 var c int = 0xff fmt.Printf("%x \n", c) // ff fmt.Printf("%X \n", c) // FF }
4.2 浮点型
Go语言支持两种浮点型数:float32
和float64
。这两种浮点型数据格式遵循IEEE 754标准: float32
的浮点数的最大范围约为 3.4e38,可以使用常量定义:math.MaxFloat32
。 float64
的浮点数的最大范围约为 1.8e308
,可以使用一个常量定义:math.MaxFloat64
。
打印浮点数时,可以使用fmt包配合动词%f:
func main() { fmt.Printf("%f\n", math.Pi) fmt.Printf("%.2f\n", math.Pi) }
4.3 复数
complex64
和complex128
var c1 complex64 c1 = 1 + 2i var c2 complex128 c2 = 2 + 3i fmt.Println(c1) fmt.Println(c2)
复数有实部和虚部,complex64
的实部和虚部为32位,complex128
的实部和虚部为64位。
4.4 布尔值
Go语言中以bool
类型进行声明布尔型数据,布尔型数据只有true(真)
和false(假)
两个值。
注意:
- 布尔类型变量的默认值为
false
。 - 不允许将整型强制转换为布尔型.
- 布尔型无法参与数值运算,也无法与其他类型进行转换。
4.5 字符串
Go语言中的字符串以原生数据类型出现,使用字符串就像使用其他原生数据类型(int、bool、float32、float64
等)一样。字符串的内部实现使用UTF-8编码。 字符串的值为双引号(")中的内容,可以在源码中直接添加非ASCII码字符:
s1 := "hello" s2 := "你好"
字符串转义符:
Go 语言的字符串常见转义符包含回车、换行、单双引号、制表符等,如下表所示。
转义符 | 含义 |
---|---|
\r | 回车符(返回行首) |
\n | 换行符(直接跳到下一行的同列位置) |
\t | 制表符 |
\' | 单引号 |
\" | 双引号 |
\\ | 反斜杠 |
func main() { fmt.Println("str := \"d:\\go\\go.exe\"") }
多行字符串:
定义一个多行字符串时,就必须使用反引号
字符:
s1 := `第一行 第二行 第三行 ` fmt.Println(s1)
反引号间换行将被作为字符串中的换行,但是所有的转义字符均无效,文本将会原样输出。
字符串的常用操作:
介绍 | 方法 |
---|---|
求长度 | len(str) |
拼接字符串 | +或fmt.Sprintf |
分割 | strings.Split |
判断是否包含 | strings.contains |
前缀/后缀判断 | strings.HasPrefix,strings.HasSuffix |
子串出现的位置 | strings.Index(),strings.LastIndex() |
join操作 | strings.Join(a[]string, sep string) |
4.6 byte和rune类型
组成每个字符串的元素叫做“字符”,可以通过遍历或者单个获取字符串元素获得字符。 字符用单引号(')包裹起来,如:
var a := '中' var b := 'x'
Go 语言的字符有以下两种:
- uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。
- rune类型,代表一个 UTF-8字符。
当需要处理中文、日文或者其他复合字符时,则需要用到rune
类型。rune
类型实际是一个int32。
Go 使用了特殊的 rune
类型来处理 Unicode
,让基于 Unicode
的文本处理更为方便,也可以使用 byte
型进行默认字符串处理,性能和扩展性都有照顾。
因为UTF8编码下一个中文汉字由3~4个字节组成,所以不能简单的按照字节去遍历一个包含中文的字符串
字符串底层是一个byte数组,所以可以和[]byte
类型相互转换。字符串是不能修改的 字符串是由byte字节组成,所以字符串的长度是byte字节的长度。 rune类型用来表示utf8字符,一个rune
字符由一个或多个byte组成。
修改字符串:
要修改字符串,需要先将其转换成[]rune
或[]byte
,完成后再转换为string
。无论哪种转换,都会重新分配内存,并复制字节数组。
func changeString() { s1 := "big" // 强制类型转换 byteS1 := []byte(s1) byteS1[0] = 'p' fmt.Println(string(byteS1)) s2 := "白萝卜" runeS2 := []rune(s2) runeS2[0] = '红' fmt.Println(string(runeS2)) }
4.7 类型转换
Go语言中只有强制类型转换,没有隐式类型转换。该语法只能在两个类型之间支持相互转换的时候使用。
强制类型转换的基本语法如下:
T(表达式)
其中,T表示要转换的类型。表达式包括变量、复杂算子和函数返回值等.
func sqrtDemo() { var a, b = 3, 4 var c int // math.Sqrt()接收的参数是float64类型,需要强制转换 c = int(math.Sqrt(float64(a*a + b*b))) fmt.Println(c) }
运算符用于在程序运行时执行数学或逻辑运算。
5、运算符
Go 语言内置的运算符有:
- 算术运算符
- 关系运算符
- 逻辑运算符
- 位运算符
- 赋值运算符
5.1 算数运算符
运算符 | 描述 |
---|---|
+ | 相加 |
- | 相减 |
* | 相乘 |
/ | 相除 |
% | 求余 |
注意: ++
(自增)和--(
自减)在Go语言中是单独的语句,并不是运算符。
5.2 关系运算符
运算符 | 描述 |
---|---|
== | 检查两个值是否相等,如果相等返回 True 否则返回 False。 |
!= | 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 |
> | 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 |
>= | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 |
检查左边值是否小于右边值,如果是返回 True 否则返回 False。 | |
检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。 |
5.3 逻辑运算符
运算符 | 描述 |
---|---|
&& | 逻辑 AND 运算符。 如果两边的操作数都是 True,则为 True,否则为 False。 |
|| | 逻辑 OR 运算符。 如果两边的操作数有一个 True,则为 True,否则为 False。 |
! | 逻辑 NOT 运算符。 如果条件为 True,则为 False,否则为 True。 |
5.4 位运算符
位运算符对整数在内存中的二进制位进行操作。
运算符 | 描述 |
---|---|
& | 参与运算的两数各对应的二进位相与。 (两位均为1才为1) |
| | 参与运算的两数各对应的二进位相或。 (两位有一个为1就为1) |
^ | 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 (两位不一样则为1) |
&^ | 二进制位清空&^ |
左移n位就是乘以2的n次方。 “a | |
>> | 右移n位就是除以2的n次方。 “a>>b”是把a的各二进位全部右移b位。 |
A | B | A&B | A|B | A^B |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 1 |
5.5 赋值运算符
运算符 | 描述 | 示例 |
---|---|---|
= | 简单的赋值操作符,分配值从右边的操作数左侧的操作数 | C = A + B 将分配A + B的值到C |
+= | 相加并赋值运算符,它增加了右操作数左操作数和分配结果左操作数 | C += A 相当于 C = C + A |
-= | 减和赋值运算符,它减去右操作数从左侧的操作数和分配结果左操作数 | C -= A 相当于 C = C - A |
*= | 乘法和赋值运算符,它乘以右边的操作数与左操作数和分配结果左操作数 | C *= A 相当于 C = C * A |
/= | 除法赋值运算符,它把左操作数与右操作数和分配结果左操作数 | C /= A 相当于 C = C / A |
%= | 模量和赋值运算符,它需要使用两个操作数的模量和分配结果左操作数 | C %= A 相当于 C = C % A |
左移位并赋值运算符 | C | |
>>= | 向右移位并赋值运算符 | C >>= 2 相同于 C = C >> 2 |
&= | 按位与赋值运算符 | C &= 2 相同于 C = C & 2 |
^= | 按位异或并赋值运算符 | C ^= 2 相同于 C = C ^ 2 |
|= | 按位或并赋值运算符 | C |= 2 相同于 C = C | 2 |
5.6 运算符优先级
有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。由上至下代表优先级由高到低:
优先级 | 运算符 |
---|---|
7 | ~ ! ++ -- |
6 | * / % > & &^ |
5 | + - ^ |
4 | == != = > |
3 | |
2 | && |
1 | || |
当然,可以通过使用括号来临时提升某个表达式的整体运算优先级。
文中关于golang的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Golang通脉之数据类型详情》文章吧,也可关注golang学习网公众号了解相关技术文章。
-
230 收藏
-
136 收藏
-
212 收藏
-
267 收藏
-
281 收藏
-
438 收藏
-
439 收藏
-
239 收藏
-
240 收藏
-
423 收藏
-
283 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习
-
- 如意的面包
- 细节满满,码起来,感谢大佬的这篇博文,我会继续支持!
- 2023-03-20 01:27:18
-
- 潇洒的酒窝
- 真优秀,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢up主分享文章!
- 2023-03-17 16:28:33
-
- 忧伤的玉米
- 这篇文章内容真及时,很详细,很好,码起来,关注老哥了!希望老哥能多写Golang相关的文章。
- 2023-03-03 19:29:07
-
- 威武的鸵鸟
- 太细致了,已收藏,感谢楼主的这篇技术贴,我会继续支持!
- 2023-01-16 18:39:47
-
- 顺利的板凳
- 这篇文章太及时了,up主加油!
- 2023-01-15 10:47:35
-
- 高大的冰棍
- 感谢大佬分享,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢师傅分享博文!
- 2023-01-12 22:31:49
-
- 隐形的朋友
- 这篇文章内容太及时了,太全面了,很有用,mark,关注作者大大了!希望作者大大能多写Golang相关的文章。
- 2023-01-02 11:52:33