go笔记
-
map、slice、chan、指针、interface默认以引用的方式传递。
-
安装是最好指定版本。
-
在开始之前, 让我们确保在本地安装了最新版本的 Micro. 为此, 请在终端中运行以下命令: rm $GOPATH/bin/micro go get github.com/micro/micro/v2@master
-
grpc和gin的标准校验不太友好,建议一般业务开发可以用web模式,从而用上gin的各种自动校验。
-
还有日志监控未加---*
-
map类型的变量默认初始值为nil,需要使用make()函数来分配内存
-
Golang返回值不能用容器对象接收多返回值。只能用多个变量,或
"_"
忽略。 -
多返回值可直接作为其他函数调用实参。
-
Go实现类似 try catch 的异常处理
package main import "fmt" func Try(fun func(), handler func(interface{})) { defer func() { if err := recover(); err != nil { handler(err) } }() fun() } func main() { Try(func() { panic("test panic") }, func(err interface{}) { fmt.Println(err) }) }
-
Go语言的并发模型是CSP(Communicating Sequential Processes),提倡通过通信共享内存而不是通过共享内存而实现通信。
-
关闭已经关闭的channel也会引发panic。
-
声明的通道后需要使用make函数初始化之后才能使用。
-
select可以同时监听一个或多个channel,直到其中一个channel ready;如果多个channel同时ready,则随机选择一个执行。
-
golang的数据类型转换只能强制转换,不能自动转换。
-
反射调用函数名时,var.Method(1).call(), 数据值是按方法名的首字母排序的
-
在 encode/decode JSON 数据时,Go 默认会将数值当做 float64 处理
-
类型断言作用:当某个类型为interface{}的变量,真实类型为A时,才做某件事时,这时可以使用类型断言
-
reflect.DeepEqual 比较struct、array、slice 和 map,,,不能用==比较
-
在一个 defer 延迟执行的函数中调用 recover() ,它才能捕捉 / 中断 panic
-
在 range 迭代中,得到的值其实是元素的一份值拷贝,更新拷贝并不会更改原来的元素,只能通过key操作原值来改变原始的值。
-
从一个现有的非 interface 类型创建新类型时,并不会继承原有的方法:
-
没有指定标签的 break 只会跳出 switch/select 语句
-
for 语句中的迭代变量在每次迭代中都会重用,即 for 中创建的闭包函数接收到的参数始终是同一个变量,在 goroutine 开始执行时都会得到同一个迭代值:
func main() { data := []string{"one", "two", "three"} for _, v := range data { go func() { fmt.Println(v) }() } time.Sleep(3 * time.Second) // 输出 three three three } 最简单的解决方法:无需修改 goroutine 函数,在 for 内部使用局部变量保存迭代值,再传参: for _, v := range data { vCopy := v go func() { fmt.Println(vCopy) }() }
-
对 defer 延迟执行的函数,会在调用它的函数结束时执行,而不是在调用它的语句块结束时执行,注意区分开。
-
直接在处理 HTTP 响应错误的代码块中,直接关闭非 nil 的响应体;手动调用 defer 来关闭响应体。
-
字符串用双引号,字符用单引号,字符分为uint8类型,或者叫 byte 型,代表了ASCII码的一个字符、 rune类型,代表一个 UTF-8字符两种;
-
当需要处理中文、日文或者其他复合字符时,则需要用到
rune
类型。rune
类型实际是一个int32
。 Go 使用了特殊的rune
类型来处理Unicode
,让基于Unicode
的文本处理更为方便,也可以使用byte
型进行默认字符串处理,性能和扩展性都有照顾
-
-
切片(slice)是对数组一个连续片段的引用,所以切片是一个引用类型;make 函数允许在运行期动态指定数组长度,绕开了
数组类型必须使用编译期常量
的限制。 -
指针:只需要记住两个符号:
&
(取地址)和*
(根据地址取值) -
Go语言中有个判断map中键是否存在
scoreMap
-
结构体是用来描述一组值的。只有当结构体实例化时,才会真正地分配内存。也就是必须实例化后才能使用结构体的字段。
-
Go range循环时他的值的地址是固定的,所以当地址赋值是要注意不能红val,只有取值可以用val,地址要根据key取值:结构体 · Go语言中文文档
-
go协成住逻辑退出了,协程也会退出
-
Go语言的并发模型是CSP(Communicating Sequential Processes),提倡通过通信共享内存而不是通过共享内存而实现通信。
-
Go 语言中的通道(channel)是一种特殊的类型。通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。
-
channel是一种类型,一种引用类型;声明的通道后需要使用make函数初始化之后才能使用。
-
但关闭通道不是必须的。关闭一个已经关闭的通道会导致panic。对一个关闭的通道再发送值就会导致panic。对一个关闭的通道进行接收会一直获取值直到通道为空。对一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值。
-
无缓冲的通道,无缓冲的通道只有在有人接收值的时候才能发送值
-
切片如果没有引起扩容则会不会生成新的切片,就会改变原来的值;
-
一个channel同时仅允许被一个goroutine读写
-
因读阻塞的goroutine会被向channel写入数据的goroutine唤醒;
-
因写阻塞的goroutine会被从channel读数据的goroutine唤醒
-
-
WaitGroup:主协成不方便控制子协成,只有一级多协成时用这个。context主协成可以控制子协成。有多级协成,且主协成需要控制子协成时使用。