1. 命名规范1.1 文件Go 语言中,源文件以 .go 格式保存,例如 main.go,且文件名只能由小写字母组成,若有多个单词,可以用下划线 _ 进行拼接,例如 my_file.go。
1.2 标识符Go 语言中,标识符是区分大小写的,标识符必须以字符或 _ 开头,后面可以跟 0 个或多个字符(字母、数字以及其他符号),例如 _,_abc,a1,b_2。同时标识符不能是 Go 语言中的保留关键字,不能以数字开头,也不能有运算符。
以下这些标识符是错误的:
2c(不能以数字开头)
switch(不能是保留关键字)
m+n(不能出现运算符)
_ 是一个特殊的标识符,叫做空白标识符。它既可以被赋值或定义(任意类型的数据),但它接收的值将被抛弃,无法在代码中继续使用。有时候函数会返回多个值,我们可能不需要使用某些值,便可以用 _ 来接收,提高代码的灵活性。
用 _ 接收的变量统称为匿名变量。
1.3 保留关键字以下是 Go 语言中的保留关键字:
保留关键字仅 25 个,还是比较少的,有利于加快编译速度。
12345break default func ...
1. 常量1.1 常量的定义常量是一种特殊的变量,被初始化之后就无法再改变。
Go 语言中,常量的类型只能是布尔型,数字型(整型、浮点型和复数)和字符串型。
常量可以使用关键字 const 来定义,定义格式为 const variable [type] = value。
12const m string = "abc" // 显示声明const n = "xyz" // 隐式声明
常量的值必须在编译时能确定,给常量赋值时可以涉及表达式的计算,但计算值必须能在编译时确定。
12const m = 2/3 // 正确const n = getValue() // 错误,编译时自定义函数属于未知,无法用于常量赋值,但可以使用内置函数,如 len()
1.2 枚举常量也可以用于枚举:
Unknown 表示未知性别,Female 表示女性,Male 表示男性。
12345const ( Unknown = 0 Female = 1 Male = 2)
itoa 是一个特殊的常量,itoa 在 const 关键字出现时被重置为 0 ...
前言流程控制是每门语言控制程序逻辑和执行顺序的重要组成部分,Go 语言中常见的流程控制有 if,for,switch;break、continue 和 goto 是为了简化流程控制,降低代码复杂度。
if-elseif 分支结构的基本写法为:
if 分支结构多用于条件判断。
1234567if 表达式1 { 分支1} else if 表达式2 { 分支2} else { 分支3}
上述代码中,若表达式1的值为 true,程序将会执行分支1;若表达式1的值为 false,继续判断表达式2,若表达式2为 true,将会执行分支2;若表达式1和表达式2都为false,将会执行分支3。
if-else 分支结构会逐层判断表达式是否为 true,若为 true,则执行该表达式中对应的分支,否则继续判断下一个表达式,依次类推。
我们来看一个例子:
12345678910111213141516171819package mainimport "fmt"func testIf(score int) ...
数组初始化数组可以保存指定长度的多个数据,且这些数据的类型都相同,数据类型可以是原始类型,如整型和字符串等,也可以是自定义类型。
数组通过索引来访问元素,索引从 0 开始,第一个元素的索引为 0,第二个为 1,依此类推。
在 Go 语言中声明数组的格式为:
1var variable [len]type
例如,声明名称为arr1,长度和类型分别为5和 int 的数组:
1var arr1 [5]int
我们可以让编译器根据元素个数自动推断数组长度,只需要在声明长度时用 ... 替代:
1var numArray = [...]int{1, 2, 3}
我们还可以根据索引来声明数组:
1a := [...]string{0: "北京", 1: "上海"} // 索引 0 对应的元素为"北京",1 对应的元素为"上海"
整型数组中所有元素都初始化为 0,数组 arr中第 i 个元素为arr[i - 1],最后一个元素为 arr[len(arr) - 1]。
数组是 ...
1. 使用接口的原因我们来看一段代码:
1234567891011121314type Cat struct{}func (c Cat) Say() string { return "喵喵喵" }type Dog struct{}func (d Dog) Say() string { return "汪汪汪" }func main() { c := Cat{} fmt.Println("猫:", c.Say()) d := Dog{} fmt.Println("狗:", d.Say())}
上述代码中定义了狗 Dog 和猫 Cat 以及它们对应的方法 Say(),若要继续添加鸭 Duck 方法和其对应的方法 Say(),重复代码会非常多。我们可不可以从这三种动物类型中抽象出方法 Say(),这就是接口的作用,接口可以定义抽象方法,来规范我们的代码。
2. 接口的定义和 ...
反射是用程序检查其所拥有的结构,尤其是类型的一种能力。反射可以在运行时(不必在编译时)检查类型和变量,例如大小、变量、方法和动态调用这些方法。
方法和类型的反射reflect 包提供了反射功能,它定义两个重要类型:Type 和 Value,分别表示动态类型和值。
有两个常用的方法:
reflect.TypeOf:返回对象的具体类型。
reflect.ValueOf:返回对象的值。
反射是先检查一个接口的值,再将变量转换成空接口类型,我们看下这两个函数的定义就能明白了:
12func TypeOf(i interface{}) Typefunc ValueOf(i interface{}) Value
reflect.TypeOf函数 reflect.Typeof() 可以接收任意 interface{} 类型数据,并返回其动态类型。
123456789101112package mainimport ( "fmt" "reflect")func main() { t := reflect. ...
传递变长参数如果函数最后一个参数采用 ...type 的形式,那么这个函数就可以处理一个变长参数(长度可以为 0),这样的函数被称为变参函数,如:
1func myFunc(a int, args ...int)
如果参数存储在切片 arr 中,可以用 arr... 来传递参数,如:
123456789101112131415161718192021222324252627package mainimport "fmt"func main() { x := Min(1, 3, 2, 0) fmt.Printf("The minimum is: %d\n", x) arr := []int{7, 9, 3, 5, 1} x = Min(arr...) fmt.Printf("The minimum in the arr is: %d", x)}func Min(a ...int) int { if len(a) == 0 { ...
基本概念线程和进程
进程 :是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个 独立单位 。
线程 :是进程的一个执行实体,是 CPU 调度和分派的 基本单位 ,它是比进程更小的能独立运行的 基本单位 。
一个进程可以创建或撤销多个线程;同一个进程中的多个线程之间可以并发执行。
线程和协程
协程 :独立栈空间,共享堆空间,调度由用户自己控制,本质上有点类似于用户级线程,这些用户级线程的调度也是自己实现的。
线程 :一个线程上可以跑多个协程,协程是轻量级的线程。
并发和并行并发 和 并行 虽然相似,但是有所不同:
并发 :逻辑上具备同时处理多个任务的能力。
并行 :物理上在同一时刻执行多个并发任务。
我们一般会说程序是并发的,意思是说它允许多个任务同时进行,但不一定在同一时刻发生。对于单核处理器,它们能以间隔方式切换运行;而并行则依赖多核心处理器,是让多个任务真正能在同一时刻运行,是一种程序运行的状态。
多线程和多进程是并行的基本条件,但单线程也可用协程(coroutine)做到并发。虽然单线程只能通过主动切换来实现并发,但也有优点,可以避免由于切换线程导致的资源消耗 ...
Go 没有像 Java 那样的 try/catch 异常处理机制,而是用 defer/panic/recover 机制来处理异常。
Go 语言的设计者认为 try/catch 机制使用过于泛滥,而且从底层向高层抛出错误太耗费资源,因此他给 Go 语言设计了一种返回值处理错误方式:通过在函数和方法中返回错误对象,这个错误对象一般在多个返回值的最后;如果返回 nil,则表明没有错误,且主调函数应该检查并处理每一个错误。
我们通过调用 pack1 包中的 Func1 函数来了解 Go 语言中的错误处理方式:
Func1返回了两个值,一个 value和 err,err 是错误对象,若 err 不为 nil(nil 是空的意思,类似于 Java 中的 null),则进行错误处理,打印出具体错误信息。
1234if value, err := pack1.Func1(param1); err != nil { fmt.Printf("Error %s in pack1.Func1 with parameter %v", err.Error(), param1 ...
1. Go 语言介绍1.1 Go 语言的发展Go 语言又称 Golang,起源于 2007 年,来自于谷歌内部的一个项目,于 2009 年正式对外发布。创始团队有三人,都是计算机界的大佬:
Robert Griesemer:参与开发 Java HotSpot 虚拟机
Rob Pike:Go 语言项目总负责人,贝尔实验室 Unix 团队成员,参与的项目包括 Plan 9,Inferno 操作系统和 Limbo 编程语言
Ken Thompson:C 语言、Unix 和 Plan 9 的创始人之一
Go 语言是开源的,通过开源社区的力量得到了快速发展,越来越多的开发者开始使用 Go 语言。自 Go 语言发布以来,超过 200 名非谷歌员工贡献者对 Go 语言核心部分提交了超过 1000 个修改建议。在过去的 18 个月里,又有 150 开发者贡献了新的核心代码。
根据 TIOBE 2020 年 8 月份的编程语言排行榜,Go 语言位列第 11 位。
国内也有很多大厂在用 Go 语言,包括腾讯、阿里、百度、B 站、知乎等,我们可以看到 Go 语言的潜力还是非常大 的。
1.2 Go 语 ...
