Go 语言入门
本文介绍学习 Go 语言一些学习材料,总结学习 Go 时容易理解错误的一些概念,可用于已掌握 C++、Java 等编程语言的程序员快速入门 Go。
1. 基础语法
入门 Go 语言基础语法和关键语言概念的最佳材料是 Go 语言官方提供的在线教程:
这一在线教程提供了文档+在线编程环境,可在浏览器中编辑和运行代码。同时,也穿插了一些小练习,能够在写代码中学习 Go 语言。学习完该教程预估要几个小时,学习完后即可使用 Go 语言编写自己的程序。
这一教程涵盖的内容大概包括:
- 基本数据类型:
int
、float64
、string
等 Go 语言支持的基本数据类型,以及定义变量、常量、函数内变量的语法等; - 常用容器:包括
slice
、map
等数据结构,分别提供可变长数组、哈希等功能; - 控制语句:
if
、for
、switch
等控制语句结构,尤其是 Go 语言提供的类似于if expression; bool
的语法; - 函数与接口:Go 语言中函数定义语法、多返回值、接口定义与实现、结构体方法等;
- 并发:介绍 Go
语言提供的并发编程相关概念,包括:
goroutine
、select
、channel
等的使用。
学习完这些内容后,该教程也指出了继续学习的方向,链接:https://tour.go-zh.org/concurrency/11 。
2. 值传递 or 引用传递?
学习完 Go
基础语法后,难免会遇到一个问题:为什么同样是语法上的以值传递,对
int
等类型的修改不改变函数外参数;而对
map
、slice
、channel
的更改却会改变传递给函数的原参数。乍一看,这似乎类似于 Java
语言中的机制:对基本类型以值传递;对对象类型引用传递。但是这一理解实际上是不对的,Go
语言中只存在以值传递。看似 “引用传递” 实际上是 Go
语言为了方便我们使用所做的一层隐藏或抽象。
对 Go 以值传递的介绍文章网上已有很多,这里贴两个链接供参考:
简单来说就是:
- Go 语言函数传参只存在以值传递;
map
、channel
等语言提供的功能,其本质上是调用make_xxx
函数并返回指针类型,语言隐藏了其实际上是指针的事实,从而方便程序员使用;slice
更为特殊,其本质上是一个结构体,内部含有指向堆内存的指针,因此函数传递slice
时,需要做结构体拷贝,但是由于指针实际上指向堆内存,通过下标访问arr[i]
并进行更改时,更改也对函数体外的原slice
可见。
3. 并发编程
Go 语言提供的 goroutine
和 channel
提供了一种抽象层级更高的并发编程模型,而不是传统的面向锁、条件变量等的并发编程。个人认为,初次学习
Go
的并发编程时还是比较难理解的,尤其是思维方式的转变,从习惯的:共享数据结构(内存)+锁的并发编程,转向
Go 语言的:如何定义消息和划分读写 channel
功能,以使用
goroutine
和 channel
进行并发编程。这是完全两种不同的思考方式,需要花费一定时间来转换。这里提供一些可参考的资料以学习
Go 并发编程的惯用法:
- Go 并发模型(幻灯片) :Go 语言设计者之一关于 Go 并发编程模式的演讲视频;
- 深入 Go 并发模型(幻灯片) :Google 的另一关于 Go 并发编程的演讲视频;
- Codewalk: 通过通信共享内存 :通过通信来共享内存示例;
- lotusirous/go-concurrency-patterns: Concurrency patterns in Go (github.com) :收集了常用 Go 并发编程模式的 GitHub 仓库。