这是我参与「第五届青训营」伴学笔记创作活动的第1天。今天复习了go的相关基础语法,并将一些值得注意的点记录了下来。
什么是go语言
- 高性能、高并发
- 不需借助复杂的第三方库即可开发高并发应用程序
- 语法简单,学习曲线平缓
- 类似C,去掉了表达式括号,循环只有一种方式
- 丰富的标准库
- 很高的稳定性和兼容性保障
- 享受语言迭代带来的性能优化
- 完善的工具链
- 编译、代码格式化、错误检查、帮助文档、包管理、代码补充提示、
- 单元测试框架:支持单元测试、性能测试、代码覆盖率等
- 静态链接
- 线上的容器环境中,部署体积非常小
- 快速编译
- 静态语言中几乎最快的编译速度
- 跨平台
- 常见的操作系统:Windows,Linux等
- 移动平台:安卓,ios
- 路由器、树莓派
- 支持交叉编译
- 垃圾回收
基础语法以及与其他语言的区别
go快速生成代码片段
- pkgm
package main
func main() {
}
- ff
fmt.Printf("", var)
- for
for i := 0; i < count; i++ {
}
- forr
for _, v := range v {
}
- fmain
func main() {
}
go中的if语句
- 不需要使用括号将条件包含起来
- 大括号
{}必须存在,即使只有一行语句 - 左括号必须在
if或else的同一行 - 在
if之后,条件语句之前,可以添加变量初始化语句,使用;进行分隔
go中的switch语句
- 支持多条件匹配
- 不同的
case之间不使用break分隔,默认只会执行一个case - 如果想要执行多个
case,需要使用fallthrough关键字,也可用break终止。 - 分支还可以使用表达式,例如:
a>0
go中的for语句
- go语言中的
for循环,只有for关键字,去除了像其他语言中的while和do while. - go中的for语句表达式不用加括号.
- go中的for语句的初始条件和结束条件都可以省略,在这种情况下,类似于其他语言的
while语句. - 只写for不写任何表达式相当于无限循环.
- Go语言中可以使用
for range遍历数组、切片、字符串、map 及 channel。 通过for range遍历,数组、切片和字符串返回索引和值,map返回键和值,channel只返回通道内的值.
go中的循环控制语句
带标签的break,可以跳出多层作用域,不需要一层一层跳出.continue和goto也是如此.
go中的数组和切片
- 数组长度和元素类型共同组成数组的类型.
- 数组长度可以省略,使用
...代替,初始化值的数量自动推断. - 数组可以通过指定索引值的方式来初始化,未指定所有的默认未零值.
- 切片是一个拥有相同类型元素的可变长度的序列。切片可以理解为,可变长度的可以自动扩容的数组.
- 切片有自己的长度和容量,可以通过使用内置的
len()函数求长度,内置的cap()函数求切片的容量. - 切片可以使用
append()函数添加元素。由于切片是引用类型,通过赋值的方式,会修改原有内容,go提供了copy()函数来拷贝切片。p := []int{1,2,3,4,5} q := make([]int,5) copy(q,p)
go中的map
- 判断map中某个键是否存在:
value, ok := map[key] //判断ok是否为true即可判断key是否存在
go中的函数
- go语言中有3种函数:普通函数、匿名函数、方法(定义在struct上的函数)。
- go语言中不允许函数重载。
- go语言中的函数不能嵌套函数,但可以嵌套匿名函数。
- 函数是一个值,可以将函数赋值给变量,使得这个变量也成为函数。
- 函数可以作为参数传递给另一个函数。
- 函数的返回值可以是一个函数。
- 函数调用的时候,如果有参数传递给函数,则先拷贝参数的副本,再将副本传递给函数。
- 函数参数可以没有名称。
函数参数
- go语言函数可以有0或多个参数,参数需要指定数据类型。
- go语言是通过传值的方式传参的,意味着传递给函数的是拷贝后的副本。
map、slice、interface、channel这些数据类型本身就是指针类型的,所以就算是拷贝传值也是拷贝的指针,拷贝后的参数仍然指向底层数据结构,所以修改它们可能会影响外部数据结构的值。 - go语言可以使用变长参数,有时候并不能确定参数的个数,可以使用变长参数,可以在函数定义语句的参数部分使用
ARGS...TYPE的方式。这时会将...代表的参数全部保存到一个名为ARGS的slice中。
函数返回值
- 函数可以有0或多个返回值,返回值需要指定数据类型,返回值通过
return关键字来指定。 return关键字中指定了参数时,返回值可以不用名称。如果return省略参数,则返回值部分必须带名称。- 当返回值有名称时,必须使用括号包围,逗号分隔,即使只有一个返回值。
- 即使返回值命名了,
return中也可以强制指定其它返回值的名称,也就是说return的优先级更高 - 命名的返回值是预先声明好的,在函数内部可以直接使用,无需再次声明。
函数类型
- 可以用type关键字来定义一个函数类型。
- 可以使用函数类型来声明函数变量。
匿名函数
- go语言函数不能嵌套,但是在函数内部可以定义匿名函数,实现简单的功能调用。匿名函数可以自己调用自己执行。
func (参数列表)(返回值)
go中的指针
- go中的函数传参都是值拷贝,当期望修改某个变量的时候,可以创建一个指向该变量地址的指针。
- go中的指针不能进行偏移和运算。
go中的结构体
- go没有面向对象的概念,但可以使用结构体来实现面向对象编程的一些特性:继承、组合等。
- 结构体成员在没有赋值之前都是零值(0,0.0,false,nil等),可以使用
.运算符来访问结构体成员。 - 如果结构体是临时使用,可以使用匿名结构体。
package main import "fmt" func main() { var person struct { name string age int } person.name = "小杰" person.age = 18 fmt.Printf("%v\n", person) } - 可以使用
new关键字创建结构体指针,访问结构体指针成员,也使用点运算符.。 - go结构体可以像普通变量一样,作为函数的参数,传递给函数。直接传递结构体,将是一个副本,在函数内部不会改变外面结构体内容。当传递结构体指针时,在函数内部,能够改变外部结构体的内容。
- go语言没有面向对象编程思想,也没有继承关系,但是可以通过结构体嵌套来实现这种效果。
go中的方法
- Go中的方法,是一种特殊的函数,定义于struct之上,方法和函数非常相似,只是多了一个接受类型:
type mytype struct{} func (recv mytype) my_method(para) return_type {} func (recv *mytype) my_method(para) return_type {} - 方法的receiver type并非一定要是struct类型,type定义的类型别名、slice、map、channel、func类型等都可以。
- struct结合它的方法就等价于面向对象中的类。只不过struct可以和它的方法分开,并非一定要属于同一个文件,但必须属于同一个包。
- 方法有两种接收类型:
(T Type)和(T *Type),它们之间有区别。 - go中没有方法重载(overload)的说法,也就是说同一个类型中的所有方法名必须都唯一。
- 如果receiver是一个指针类型,则会自动解除引用。
- 方法和type是分开的,意味着实例的行为(behavior)和数据存储(field)是分开的,但是它们通过receiver建立起关联关系。
- Go中的方法,是一种特殊的函数,定义于struct之上,方法和函数非常相似,只是多了一个接受类型: