这是我参与「第三届青训营 -后端场」笔记创作活动的的第 1 篇笔记
Go语言快速上手
语言特性
- 高性能、高并发
- 语法简单
- 丰富标准库
- 完善工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
基础语法
变量
go语言是一门强类型语言,每一个变量都有它自己的变量类型。常见的变量类型包括 字符串整数浮点型、布尔型等。go语言的字符串是内置类型,可以直接通过加号(+)拼接,也能够直接用等号(=)去比较两个字符串。 var声明语句可以创建一个特定类型的变量,然后给变量附加一个名字,并且设置变量的初始值。变量声明的一般语法如下:
var 变量名字 类型 = 表达式
一组变量也可以通过调用一个函数,由函数返回的多个返回值初始化:
var f, err = os.Open(name) // os.Open returns a file and an error
在函数内部,有一种称为简短变量声明语句的形式可用于声明和初始化局部变量。它以“名字 := 表达式”形式声明变量
anim := gif.GIF{LoopCount: nframes}
freq := rand.Float64() * 3.0
t := 0.0
if else
go语言里面的if else 写法和C或者C++类似。 不同点1 : if后面没有括号。如果你写括号的话,那么在保存的时候你的编辑器会自动把你去掉。 不同点2 : Golang里面的if,它必须后面接大括号,就是你不能像C或者C++一样,直接把if里面的语句同一行。
循环
只有唯一种for循环 什么都不写是死循环,写一个=判断条件相当于while循环,写标准三段就是普通for循环,中间三段的任意一段均可以省略
switch
switch a 变量不需要括号
数组
数组是一个由固定长度的特定类型元素组成的序列
var a [3]int
var q [3]int = [3]int{1, 2, 3}
q := [...]int{1, 2, 3}
切片
Slice(切片)代表变长的序列,序列中每个元素都有相同的类型。一个slice类型一般写作[]T,其中T代表slice中元素的类型;slice的语法和数组很像,只是没有固定长度而已。
s := make([]string, 3)
s = append(s, "d")
数组和slice之间有着紧密的联系。一个slice是一个轻量级的数据结构,提供了访问数组子序列(或者全部)元素的功能,而且slice的底层确实引用一个数组对象。一个slice由三个部分构成:指针、长度和容量。
多个slice之间可以共享底层的数据,并且引用的数组部分区间可能重叠。图4.1显示了表示一年中每个月份名字的字符串数组,还有重叠引用了该数组的两个slice。数组这样定义
months := [...]string{1: "January", /* ... */, 12: "December"}
map
golang的map是完全无序的,遍历的时候不会按照字母顺序,也不会按照插入顺序输出,而是随机顺序。
m := make(map[string]int)
r, ok := m["unknow"]
range
range遍历的时候,对于数组会返回两个值,第一个是索引,第二个是对应位置的值。如果我们不需要索引的话,我们可以用下划线来忽略
m := map[string]string{"a": "A", "b": "B"}
for k, v := range m {
fmt.Println(k, v) // b 8; a A
}
函数
Golang和其他很多语言不一样的是,变量类型是后置的。Golang 里面的函数原生支持返回多个值。在实际的业务逻辑代码里面几乎所有的函数都返回两个值,第一个是真正的返回结果,第二个值是一个错误信息
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
指针
go里面也支持指针。当然,相比C和C++里面的指针,支持的操作很有限。指针的一个主要用途就是对于传入参数进行修改。
当调用一个函数时,会对其每一个参数值进行拷贝,如果一个函数需要更新一个变量,或者函数的其中一个参数实在太大我们希望能够避免进行这种默认的拷贝,这种情况下我们就需要用到指针了。对应到我们这里用来更新接收器的对象的方法,当这个接受者变量本身比较大时,我们就可以用其指针而不是对象来声明方法,如下:
func (p *Point) ScaleBy(factor float64) {
p.X *= factor
p.Y *= factor
}
结构体
结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。每个值称为结构体的成员
type user struct {
name string
password string
}
a := user{name: "wang", password: "1024"}
d.name = "wang"
//传入对象使用指针
func checkPassword2(u *user, password string) bool {
return u.password == password
}
错误处理
在Go的错误处理中,错误是软件包API和应用程序用户界面的一个重要组成部分,程序运行失败仅被认为是几个预期的结果之一。 错误处理在go语言里面符合语言习惯的做法就是使用一个单独的返回值来传递错误信息。go语言的处理方式,能够很清晰地知道哪个函数返回了错误,并且能用简单的ifelse来处理错误。
字符串
字符串格式化。在标准库的FMT包里面有很多的字符串格式相关的方法,比如 printf这个类似于c语言里面的printf函数。不同的是,在go语言里面的话,你可以很轻松地用%v来打印任意类型的变量
JSON 处理
go语言里面的JSON操作非常简单,对于一个已有的结构体,只要保证每个字段的第一个字母是大写,也就是是公开字段。那么这个结构体就能用JSON.marshaler去序列化,变成一个JSON的字符串。序列化之后的字符串也能够用JSON.unmarshaler去反序列化到一个空的变量里面。