装Go环境只需要五分钟。菜鸟官网下个安装包,教程一路下一步,菜鸟完事。教程验证一下:终端敲 go version,菜鸟蹦出来版本号就成了。教程别在Windows配环境变量上折腾太久,菜鸟没意义。教程
第一个程序永远是菜鸟hello world,这没什么好回避的教程。新建一个 main.go,菜鸟写进去:
package main import "fmt" func main() { fmt.Println("hello world") } go run main.go,教程屏幕上就出来了。菜鸟这里有两个东西值得说。教程一是菜鸟 package main,Go用包来组织代码,main包特殊,它是程序入口。二是 func main(),名字固定,不能改,改了就编译不过。我当初把main写成Main,报错看了半天才反应过来,Go大小写敏感,而且首字母大写有特殊含义,后面讲。
Go是静态类型语言,但写起来不算啰嗦。声明变量有几种方式:
var a int = 10 var b = 20 // 类型推断 c := 30 // 短声明,只能用在函数内部 := 这个符号新手容易懵,它同时完成声明和赋值。注意它不能用在函数外面。我第一次在全局作用域用 :=,编译器直接甩脸。
还有个坑:Go里声明了不用的变量会报错,不是警告,是编译错误。刚开始觉得烦,后来发现这逼着你把代码写干净。从别的语言转过来的人经常在这里翻车。
这是Go比较舒服的一个设计。比如你想返回结果和错误:
func divide(a, b float64) (float64, error) { if b == 0 { return 0, fmt.Errorf("除数不能为零") } return a / b, nil } 调用的时候 result, err := divide(10, 3),两个值一起接。Go的错误处理就是这套路,if err != nil 会跟着你一辈子。有人吐槽啰嗦,但用久了会觉得比异常机制更可控——错误在哪处理的,一眼能看见。
数组长度固定,[5]int 就是五个整数,不多不少。实际写代码基本用切片:
s := []int{ 1, 2, 3} s = append(s, 4) 切片底层还是数组,但能动态扩容。append 返回新切片,别忘了接回去。我见过有人写 append(s, 4) 然后纳闷为什么没变化,编译器其实会提示你返回值没被使用,但新手经常忽略那个提示。
Go面向对象的方式跟Java、Python都不一样。没有class,用struct:
type User struct { Name string Age int } func (u User) Greet() string { return "hi, " + u.Name } 那个 (u User) 叫接收者,相当于给User绑了个方法。没有继承,但可以组合——把一个struct嵌进另一个struct里,外层直接访问内层的字段和方法。这比继承灵活,至少不用纠结父类子类那一堆破事。
启动一个协程只要 go 一个关键字:
go doSomething() 协程比线程轻得多,开几千个不费劲。协程之间用channel通信:
ch := make(chan int) go func() { ch <- 42 }() result := <-ch channel这块内容不少,有缓冲、无缓冲、单向、select,够单独写一篇。新手先记住一点:无缓冲channel发送和接收会互相阻塞,直到两边都准备好。这个特性用好了是同步利器,用不好就是死锁。
学Go最直接的路子就是写。看完语法就去找个小项目练手,比如写个命令行工具、爬个网页、做个简易HTTP服务。Go的标准库很全,net/http 几行代码就能起一个服务器,不用先学框架。语法简单是Go的优点,但真正写好Go代码,得理解它的设计哲学——少即是多,显式优于隐式。