go入门
安装
去官网
上手
使用 go run xxx.go执行go文件
go
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
引入三方库
- 使用 go get 命令
shell
go get rsc.io/quote
问题
- 下载依赖(go get rsc.io/quote )下不下来,提示链接超时
切换国内源
shell
go env -w GOPROXY=https://goproxy.cn
变量声明
go
package main
import "fmt"
func main() {
var a string = "Runoob"
fmt.Println(a)
var b, c int = 1, 2
fmt.Println(b, c)
}
切片扩容
当切片cap不够时会进行扩容,并不总是翻倍扩容,而是通过算法选择线性扩容或者翻倍增长
map序列化
go
//demo_15.go
package main
import (
"encoding/json"
"fmt"
)
func main() {
res := make(map[string]interface{})
res["code"] = 200
res["msg"] = "success"
res["data"] = map[string]interface{}{
"username": "Tom",
"age": "30",
"hobby": []string{"读书", "爬山"},
}
fmt.Println("map data :", res)
//序列化
jsons, errs := json.Marshal(res)
if errs != nil {
fmt.Println("json marshal error:", errs)
}
fmt.Println("")
fmt.Println("--- map to json ---")
fmt.Println("json data :", string(jsons))
//反序列化
res2 := make(map[string]interface{})
errs = json.Unmarshal([]byte(jsons), &res2)
if errs != nil {
fmt.Println("json marshal error:", errs)
}
fmt.Println("")
fmt.Println("--- json to map ---")
fmt.Println("map data :", res2)
}
问题
- json反序列化时报错,指针异常
json.UnMarshal()的第二个参数需要传递 &xxx
go
func main() {
map2 := make(map[string]string)
err2 := json.Unmarshal(mapJson, &map2)
时间
go
package main
import (
"fmt"
"time"
)
func main() {
fmt.Printf("current time str : %s\n", getTimeStr())
}
func getTimeStr() string {
return time.Now().Format("2006-01-02 15:04:05")
}
tips: 格式化时间必须用 "2006-01-02 15:04:05" 这是写死的
chan 通道
理解为先进先出的队列,当缓冲值等于写入的长度时,会堵塞
go
package main
import (
"fmt"
"time"
)
func producer(ch chan string) {
fmt.Println("producer start")
ch <- "a"
ch <- "b"
ch <- "c"
ch <- "d"
fmt.Println("producer end")
}
func main() {
fmt.Println("main start")
ch := make(chan string, 3)
go producer(ch)
time.Sleep(1 * time.Second)
fmt.Println("main end")
}
defer函数
将函数延后执行,类似把一个一个函数往堆里面放
go
package main
import "fmt"
func calc(index string, a, b int) int {
ret := a + b
fmt.Println(index, a, b, ret)
return ret
}
func main() {
x := 1
y := 2
defer calc("A", x, calc("B", x, y))
x = 3
defer calc("C", x, calc("D", x, y))
y = 4
}
逃逸分析
go
package main
type Student struct {
Name string
}
func GetStudent() *Student {
stu := new(Student)
stu.Name = "tom"
return stu
}
func main() {
GetStudent()
}
返回指针类型,会发生逃逸,优化方案视情况而定。
函数传递指针和传值哪个效率高吗?我们知道传递指针可以减少底层值的拷贝,可以提高效率,但是如果拷贝的数据量小,由于指针传递会产生逃逸,可能会使用堆,也可能会增加
GC 的负担,所以传递指针不一定是高效的。
不要盲目使用变量指针作为参数,虽然减少了复制,但变量逃逸的开销可能更大。