探究技术的本质,享受技术的乐趣!这一期我们来聊聊Go中的数据类型,以及基本的逻辑结构。这一讲分为两个部分,第一部分,我先会和你谈谈我对类型的认知,然后谈谈Go中所支持的数据类型,第二部分,我会和你聊聊Go中提供的基本的逻辑结构,会更加侧重一些注意点,容易犯错的地方。那好,废话不多说,我们进入正篇
数据类型 In Go
类型的重要性
纵观全部的编程语言,除了较为底层的汇编语言外,无论是动态类型的编程语言,还是静态类型的编程语言,都有类型一说,可见类型这一语法元素的重要。那么类型究竟代表什么呢?如果你也有这个疑问,不妨听听我的答案。正如一个经典的公式:程序 = 数据 + 算法,算法我们暂且不谈,但是数据总归是需要存储在某个地方的,而运行中的程序,存储数据的地方自然是内存。我们知道操作系统通过内存隔离的手段保证的进程的独立性,也就是说每个进程的所使用的内存是不一样的,以此来保证程序的正确性。但是操作系统只保证了程序间内存的独立性,而程序内部的内存管理就只能依赖编程语言了,而编程语言的内存管理基本分为两大阵营,一类属于手动挡的需要程序员自己管理内存,一类属于自动挡,由垃圾回收器负责管理内存。
类型的作用
为了限制可以随便的对内存中的数据修改,编程语言引入类型,比如,int类型通常占用4个字节,那么以int类型定义的变量,能够任意操纵的内存大小就只有int类型规定的这四个字节,这样让程序内部使用的数据也似乎"隔离"了起来,各玩各的,互不打扰。正因如此,才使得编写一个好的程序容易起来。
Go 提供的数据类型
同其他编程语言一样,Go也提供了一些内置的数据类型,如果你学过多门编程语言,你会发现编程语言内置的数据类型就那么几种而已,无非就是 数字类型,字符类型,布尔类型,数组类型。不知道你是否有这样的疑问:为什么几乎所有的编程语言都只内置这几个基本类型。如果你现在还没有答案,不妨听听我的答案,因为内置的这几种数据类型通过相互组合足以对现实世界抽象建模。而在各个编程语言中组合这些基本类型的数据类型要么是结构体,要么是类。而Go的代码风格类C,所以提供组合这些基本数据类型的元素自然就是结构体。下面列举出常用的数据类型
- 整数类型 int家族
- 浮点数类型 float家族
- 复数类型 complex
- 字符串 string
- 字符类型 rune
- 数组类型 [len]type
- 切片类型 slice
- 映射类型 map
更加详细的数据类型相关的知识,可以参考官方文档 The Go Programming Language Specification - The Go Programming Language
逻辑结构 In Go
讲完了数据类型,按照"程序 = 数据 + 算法"这个公式,接下来我们看看Go中的逻辑结构,任何的算法到最后都是由顺序结构 ,分支结构 ,循环结构相互组合而成的。那么Go中提供了哪些语法元素来实现这些结构呢?又有哪些注意事项呢?
分支结构
分支结构有两种,一种为最为常见的if-else结构,一种是基于C改良后的switch结构,if-else结构无需多说,很简单,看看语法就好,和其他编程语言不通的是,它支持在判断之前声明变量。就像下面这样
if err := GetUserInfo(); err != nil {
// 处理逻辑...
}
而switch结构,主要用于基于值比较的分支中,但是在Go中,使用这种语法的多数是type switch, 具体可以参考文档 A Tour of Go ,使用分支结构还需要注意变量的作用域问题,如果感兴趣,后面详细聊聊。
循环结构
在Go中,循环结构只有一种,即for 结构,除了传统的for循环,还支持for range,针对for-range这种循环方式,存在几个坑,第一就是变量复用的问题,第二就是遍历的是浅拷贝后的集合
for index,data := range nums {
// 处理逻辑...
}
比如上面这段代码,我们遍历的不是nums,而是nums的副本,其次就是 :=
本为声明变量的用法,但是这里会出现变量重用,而不是反复声明。
总结
今天,我们梳理了一下Go的数据类型以及逻辑结构的基本语法,如果你想学习到更加具体的内容可以参考官方文档 https://go.dev/tour/welcome/1