当前位置:首页 > 焦点

go语言菜鸟教程

写Go代码最爽的菜鸟一点,是教程编译出来的东西就一个二进制文件,扔到服务器上就能跑。菜鸟没有虚拟机,教程没有一堆依赖包,菜鸟这种干脆利落的教程感觉,Python和Java给不了你。菜鸟

我刚开始学Go那会儿,教程最不习惯的菜鸟是它的“少”。关键字只有25个,教程语法简洁到有点寒酸。菜鸟别的教程语言里花里胡哨的特性,它一概没有。菜鸟但用久了你会发现,教程这不是菜鸟偷懒,是刻意为之——少即是多。团队里十个人写出来的Go代码,风格不会差太远。

变量声明:从 var 到 :=

Go的变量声明有好几种写法。最标准的是var name string = "Go",类型写在变量名后面,这点跟C、Java反过来。刚开始看着别扭,写两天就顺了。

函数内部可以用短变量声明,name := "Go",类型自动推断。这是日常写得最多的形式。注意:=只能在函数体内用,包级别不行。

var a int = 10 b := 20 // 自动推断为int var c, d = 1, 2 // 同时声明多个 

有个坑::=左边至少要有一个新变量,否则编译报错。这个规则逼着你注意作用域。

函数返回多值,错误处理不靠异常

Go函数可以返回多个值,最常见的就是“结果 + 错误”的组合:

func divide(a, b float64) (float64, error) {  if b == 0 {  return 0, errors.New("除数不能为零") } return a / b, nil } 

调用的时候必须显式检查error,不检查编译器不拦你,但代码review会被骂。Go没有try-catch,错误就是普通的值,一层层往上返回。写多了确实有点啰嗦,但好处是出错路径一目了然,不会突然从某个角落抛出一个异常把你炸懵。

slice 和 map:日常用得最多

数组在Go里用得少,因为长度固定。真正的主力是slice,可以理解成动态数组。

s := []int{ 1, 2, 3} s = append(s, 4) fmt.Println(len(s), cap(s)) // 4, 6 

append这个操作要注意:如果底层数组容量够,就在原数组上追加;不够就重新分配一块更大的内存,把数据拷过去。所以append的返回值必须接住,不接就丢数据了。

map就是哈希表,声明方式m := map[string]int{ "a": 1}。读一个不存在的key不会报错,返回零值。要判断key是否存在,用双返回值写法:

v, ok := m["b"] if !ok {  fmt.Println("key不存在") } 

goroutine:一行代码开并发

Go最出名的就是并发。开一个goroutine只需要在函数调用前加go:

go func() {  fmt.Println("我在另一个goroutine里跑") }() 

就这么简单。但简单不等于安全。多个goroutine同时读写同一个变量,race condition照样出。Go提供了channel来做goroutine之间的通信:

ch := make(chan int) go func() {  ch <- 42 }() result := <-ch 

channel有缓冲和无缓冲两种。无缓冲的channel发送和接收必须同时就绪,否则阻塞。这个特性可以用来做同步。

struct 和 interface

Go没有class,用struct来组织数据:

type User struct {  Name string Age int } func (u User) Greet() string {  return "Hi, " + u.Name } 

方法写在struct外面,用接收者绑定。值接收者和指针接收者的区别在于:值接收者操作的是副本,指针接收者能改原对象。

interface是隐式实现的。你不需要写implements,只要一个类型实现了interface里所有方法,它就自动满足这个interface。这个设计让代码解耦得很自然,但也容易让人搞不清谁实现了谁。我的经验是:定义小interface,一个方法那种,组合起来用。

几个容易踩的坑

Go的defer语句会在函数返回时执行,常用来关文件、释放锁。但注意defer的参数在声明时就求值了,不是执行时。这个细节在循环里容易翻车。

还有nil slice和空slice的区别。var s []int是nil slice,s := []int{ }是空slice。两者len都是0,但JSON序列化结果不一样——nil变成null,空的变成[]。做API的时候这个区别能让你debug半天。

Go的工具链很省心。go fmt统一格式,go vet查可疑代码,go test跑测试。不用折腾构建工具,标准库自带的东西够用。这点比Node.js生态里一堆选择困难症强太多。

学Go不用啃完所有语法再动手。把变量、函数、slice、map、struct、goroutine这几样搞明白,就能写正经东西了。剩下的边写边查,官方文档写得很清楚,比大多数教程靠谱。

分享到: