Go 语言简介
- golang.org —— 已墙
- https://github.com/golang
- 吉祥物:囊地鼠(Gopher)
History
- 2007, Google 创立
- Robert Griesemer,参与开发 Java HotSpot 虚拟机;
- Rob Pike,贝尔实验室 Unix 团队成员,参与的 Plan 9,Inferno OS, Limbo 语言;
- Ken Thompson,贝尔实验室 Unix 团队成员,C 语言、Unix 和 Plan 9 的创始人之一
- 2008,创建了一个 gcc 前端
- 2009.10.30, Rob Pike 对外宣称 Go ,并使用 BSD 开源
- 2012 年 3 月,Go1.0 正式发布
Resource
官网
- The Go Programming Language —— 官网
- 官方文档入口(索引)
- 英文版:
- 在线
- 本地:
godoc -http=:6060
- 中文版:-- 5 年没更新
- 在线 —— 首先从这里开始
- 本地:
go get github.com/Go-zh/godoc-i18n有个包安装不了
- 内容
- Spec
- A Tour of Go(Go 指南、Go 语言之旅)
- HelloWrold(带测试用例)
- Effective Go(实效 Go 编程)
- FAQ
- Reference
- package
- command
- 语法
- Articles
- Spec
- 英文版:
Spec
- A Tour of Go(Go 指南、Go 语言之旅) —— 第一本,静心读完
- 英文版:
go get golang.org/x/tour - 中文版:
go get -u github.com/Go-zh/tour,在线阅读 - 运行:
tour - 故障:
could not find go-tour content;- 手工 export GOPATH、GOROOT 一下,或写入 .bashrc
- 英文版:
- [Effective Go][实效go编程]
- FAQ
- 官方 Blog
- 中文:
go get -u github.com/Go-zh/blog-- 只翻译了 1、2 篇 go build && ./blog -reloadhttp://localhost:8080/
- 中文:
Book
- [The Way to Go]
- [The Golang Standard Library by Example]
- GO 命令教程 郝林
Team
- GCTT (Go Chinese Translation Team)
Website
开发环境
Runtime
重点:
go get安装到 GOPATH 下,而不是 GOROOT,所以 GOROOT 最好不与 GOPATH 混淆,以保持 GOROOT 的纯净和后期好替换、升级
go、doc、tools
- apt install 安装:Ubuntu18.04 上最新的是 v1.10
- 源码安装才能最新
apt 安装 —— 放弃
sudo apt install golang
- golang、golang-doc、golang-go、golang-race-detector-runtime、golang-src : 全是对下面的链接
- golang-1.10: 版权声明
- golang-1.10-doc: 文档
/usr/share/doc/golang-1.10-doc/html/docs.html- 阅读方式:使用
godoc见下文
- 阅读方式:使用
- golang-1.10-go:
/usr/lib/go-1.10/bin:goenvprint Go environment information —— 查看 GO 环境变量go help envgo env -jsonjson 格式给出变量go env -w NAME=VALUE设置变量的默认值go env -u NAME恢复变量默认值
- 变量:
- GOROOT: go 官方版本的位置
- GOPATH:go 工作环境的位置
go env -w GOPATH=$HOME/govi ~/.bash_profile&export GOPATH=$HOME/goexport PATH=$PATH:$(go env GOPATH)/bin:$HOME/.local/bin/
getdownload and install packages and dependencies —— 安装到 GOPATHbuildcompile packages and dependenciesgo build [xxx.go]生成一个本地可执行的文件- 不带源码生成的可执行文件名字就是代码里面 package name
- 有带源码生成的可执行文件名字是 xxx 文件名
installcompile and install packages and dependenciesruncompile and run Go programgo run [-n] xxx.go命令行运行 go 源码,分 2 步(-n可打印出来)- 用
$GOROOT/pkg/tool/linux_amd64/compile编译成 a - 用
$GOROOT/pkg/tool/linux_amd64/link链接、执行 a
- 用
cleanremove object files and cached filesdocshow documentation for package or symbolbugstart a bug reportfixupdate packages to use new APIsfmtgofmt (reformat) package sourcesgenerategenerate Go files by processing sourcelistlist packagestesttest packagestoolrun specified go toolversionprint Go versionvetreport likely mistakes in packages
gofmt(文件格式美化)
/usr/lib/go-1.10/pkg: 库文件(.a)
- golang-1.10-race-detector-runtime: 不明确
- golang-1.10-src:
/usr/share/go-1.10/src/usr/share/go-1.10/misc/usr/share/go-1.10/test
源码安装
sudo apt remove golang*wget https://dl.google.com/go/go1.13.4.linux-amd64.tar.gztar -xvf go1.13.4.linux-amd64.tar.gzsudo mv go /usr/localorsudo mv go $GOROOT—— 可选,其实一直放在~/go下也挺好的
golang.org/x/tools
apt 安装 —— 放弃
sudo apt install golang-golang-x-tools 在 /usr/bin/ 下安装了一些工具:
- benchcmp
- callgraph
- compilebench
- digraph
- fiximports
- getgo
- go-contrib-init
- godex
- godoc 根据源码注释生成文档
godoc -http=:6060&firefox http://localhost:6060
- goimports
goimports -w xxx.go自动添加 import,-w写入文件,而不是终端
- golang-bundle
- golang-eg
- golang-guru
- golang-stress
- gomvpkg
- gorename
- gotype
- goyacc
- html2article
- present
- ssadump
- stringer
- tip
- toolstash
go get 安装
4 种方法:推荐 4
go get golang.org/x/tools—— 被墙go get github.com/golang/toolscd $GOPATH/src/golang.org/x--git clone https://github.com/golang/tools.git--go get golang.org/x/toolscd $GOPATH/src/golang.org/x--git clone https://github.com/golang/tools.git--cd tools--go install
源码的 Mirror
golang.org 的 github 镜像
golang.org 上无法 go get 的解决办法: golang 在 github 上建立了一个镜像库: https://github.com/golang
go get golang.org/x/<Name>可以用如下操作替代cd $(go env GOPATH)/src/golang/x/进入 golang/x 目录git clone http://github.com/golang/<Name>.git- install 安装到 bin 或 pkg 下 -- 多种 install 方式
go install ./<Name>/...--./,/...很重要,会递归查找此包中的所有小包cd .. && go install ./x/<Name>/...-- 第 1 个./必须,第 3 个/可选cd $GOPATH/src--go install -x golang.org/x/<Name>/...-- 可以没有./了cd <Name>--go install
http://golang.org/x下有这些常用包(<NAME>)- tools
go install golang.org/x/tools/...缺什么,手工安装一下
- net
- sys
- text
- lint
- sync
- crypto
- xerrors
- tools
gopm
国人打造的自动寻找镜像项目。
go get -u github.com/gpmgo/gopm
然后可以使用 gopm get 代替 go get
包管理 Proxy
类似 Python/docker 的 registry。
- 使用 Go get Proxy
export GOPROXY=https://mirrors.aliyun.com/goproxy/阿里export GOPROXY=https://goproxy.cn七牛云赞助export GOPROXY=https://gonexus.devexport GOPROXY=https://goproxy.io/GOPROXY="https://proxy.golang.org,direct"—— 安装后默认
- 搭建 Go get Proxy
- GoProxy:
- 运行后生成一台 http,https,websocket,tcp,socks5 等协议的代理服务器
- 支持内网穿透,链式代理,通讯加密,智能 HTTP,SOCKS5 代理,域名黑白名单,跨平台,KCP 协议支持,集成外部 API。
- https://github.com/goproxy/goproxy.cn:
- 中文介绍:https://hacpai.com/article/1531111413925
- 配合 go modules 使用
go env -w GOPROXY=https://goproxy.cn,direct
- GoProxy:
公司的 Proxy
http_proxy=http://proxysz.zte.com.cn:80 go get github.com/...
GOROOT
$GROOT 下文件夹定义
/bin:包含可执行文件,如:编译器,Go 工具/doc:包含示例程序,代码工具,本地文档等/lib:包含文档模版/misc:包含与支持 Go 编辑器有关的配置文件以及 cgo 的示例/os_arch:包含标准库的包的对象文件(.a)/src:包含源代码构建脚本和标准库的包的完整源代码(Go 是一门开源语言)/src/cmd:包含 Go 和 C 的编译器和命令行脚本
Hello World
go env | grep GOPATH先查看一下当前的安装目录,默认在~/gomkdir -p ~/workspace/gocd ~/workspace/goexport GOPATH=$(pwd)更改 GOPATH ,注意仅限于本次
Build
gc
gccgo
Debug
gdb
delve
- https://github.com/go-delve/delve
go get -u github.com/go-delve/delve/cmd/dlv
Editor
Jupyter-notebook + Go
- 安装 Jupyter & Notebook
- 安装 ZeroMQ
- 下载
- libzmq-4.3.2.tar.gz :仅源码
- zeromq-4.3.2.tar.gz :源码 + 编译出的版本
tar -zxvf libzmq-4.3.2.tar.gz./autogen.sh./configuremake -j8sudo make installsudo ldconfiglibzmq 安装在/usr/local/lib下,此命令刷新/etc/ld.so.cache~缓存, gophernotes 才能找到 libzmq
- 下载
- 安装 gophernotes
go get -u github.com/gopherdata/gophernotesmkdir -p ~/.local/share/jupyter/kernels/gophernotescp $(go env GOPATH)/src/github.com/gopherdata/gophernotes/kernel/* ~/.local/share/jupyter/kernels/gophernotes
- 远程访问
- 需要关闭 Client 上浏览器的 Proxy
VSCode + Go
- MicroSoft 官方 Go 扩展
- 依赖于一堆的 go 第三方 tools,需要另外安装(VSCode 会自动安装到 GOPATH 中)
- gocode: 自动填充提示
- gopkgs: 列出可导入的包列表,主要用于包导入时的提示功能
- go-outline: 解析 go 文件中的函数定义,结构体定义,依赖的包等信息并以 json 格式的数据输出,用于生成符号表
- go-symbols:
- guru:
- gotests:
- gomodifytags:
- impl:
- fillstruct:
- goplay:将代码发送到 https://play.golang.org/ 执行
- godoctor:
- dlv:
- gocode-gomod:
- godef:
- goreturns: 当函数定义有返回值但返回值未设置时,自动添加返回对应类型的默认值
- golint:
- 一些 tools 可以安装成功,一些从 golang.org(被墙) 上获取的 tools 会安装失败,解决办法:
cd $(go env GOPATH)/srcmkdir -p golang.org/xcd golang.org/xgit clone https://github.com/golang/tools.git
- 依赖于一堆的 go 第三方 tools,需要另外安装(VSCode 会自动安装到 GOPATH 中)
Atom + Go-Plus
Sublime Text + GoSublime
VIM + Vim-Go
IDE
GoLand(jetbrains)
Komodo
LiteIDE
Eclipse + GoClipse
GoClipse
语法
一般结构
//当前程序的包名
package main
//导入其它的包
import "fmt"
//全部变量的声明与赋值
var name = "gopher"
//一般类型的声明
type newType int
//结构的声明
type gopher struct{}
//接口的声明
type golang interface{}
//由main函数作为程序入口点启动
func main() {
fmt.Println("Hello World!")
}
import
- import 的几种形式
import std "fmt" // 别名
import . "fmt" // 省略调用(这样可以不用写包名,直接调用)
import _ "github.com/go-sql-driver/mysql" // 初始化,但不调用
- 变量名首字母大写,才能被其他包引用
var Name = "myname" // 变量名大写,才能被其他包引用,类似于java中的public关键字
变量
- 4 种定义方式
var a string = "foo" // 新定义:定义 + 指定类型 + 赋值
var b string // 预先定义:定义 + 指定类型 ,不赋值
c := "bar" // 自动新定义:定义 + 自动类型 + 赋值
a = "fooooooo" // 覆盖: 重新赋值
- 函数外的每个语句都必须以关键字开始(var, func 等等)
:=短变量声明方式仅能用于函数内
常量
// 定义单个常量
const a int = 1
const b = "A"
// 常量组
const (
text = "123"
length = len(text)
num = b * 20
)
const (
a = "A"
b
c
//此时 a,b,c都为"A":如果不提供初始值,则表示使用上行的表达式
)
const ( // 每遇到一个const关键字,iota就会重置为0
a = "A"
b
c = iota // iota是常量的计数器,从0开始,组中每定义1个常量自动递增1,所以 c=2
d //d的值为3,因为在常量组中,定义了4个变量所以iota计数器从0开始计数4次,所以为3
)
//同时定义多个变量
const i, j, k = 1, "2", "3"
const (
text2 ,length2, num2 = "456", len(text2), k* 10
)
// 错误的定义
var a = 1
const (
b = a //此时报错,因为全局变量在编译时不能确定值,常量必须是编译时能确定值的或使用内置函数获得的值
)
函数
- 类型在变量名 之后
func add(x int, y int) int { // 可以写成 (x,y int)
return x + y
}
- 多值回传-Multiple Value
func test() (string, int) {
return "YamiOdymel", 123456
}
username, time := test() // 不必用(python的元祖、list等)
fmt.Println(username, time)
- 匿名函数
a := func() {
fmt.Println("Hello, world!")
}
a()
-
defer
-
推迟执行
-
用途:
- 函式结束的时候自动执行某些程式
Array
List
- 定义
var a [2]string
a[0] = "foo"
a[1] = "bar"
a := []string{"foo", "bar"}
fmt.Println(a[0]) // 輸出:foo
- 切片
p := []int{1, 2, 3, 4, 5, 6}
fmt.Println(p[0:1]) // 輸出:[1]
fmt.Println(p[1:1]) // 輸出:[] (!注意這跟 PHP 不一樣!)
fmt.Println(p[1:]) // 輸出:[2, 3, 4, 5, 6]
fmt.Println(p[:1]) // 輸出:[1]
Map
data := make(map[string]string) // 需要先用make()宣告map。
data["username"] = "YamiOdymel"
data["password"] = "2016 Spring"
fmt.Println(data["username"]) // 輸出:YamiOdymel
循环
- for
for i := 0; i < 3; i++ {
fmt.Println(i) // 輸出 012
}
j := 0
for ; j < 5 ; j++ {
fmt.Println(j) // 輸出:01234
}
- foreach: 通过 range 实现
data := []string{"a", "b", "c"}
// range 的功能是依次返回 下标和值
for index, value := range data {
fmt.Printf("%d%s|", index, value) // 輸出:0a|1b|2c|
}
for index := range data {
fmt.Printf("%d|", index) // 輸出:0|1|2|
}
for _, value := range data {
fmt.Printf("%s|", value) // 輸出:a|b|c|
}
- 用 for 实现 while
i := 0
for i < 3 {
i++
fmt.Println(i) // 輸出:123
}
for {
fmt.Println("WOW") // 輸出:WOWWOWWOWWOWWOW...
}
错误处理
try...catch —— NO!
panic...recover
- 一但你执行了 panic()你的程式就会宣告而终,但是别担心,因为程式结束的时候会呼叫 defer
- defer 中执行 recover()让程式不再继续进行结束动作,这就像是捕捉异常。
Struct
- 实现 Class 的功能
type Foobar struct {
a string
}
// 定義一個屬於 Foobar 的 test 方法
func (f *Foobar) test () {
// 接收來自 Foobar 的 a(等同於 PHP 的 `$this->a`)
fmt.Println(f.a)
}
b := &Foobar{a: "hello, world!"}
b.test() // 輸出:hello, world!
Goroutine
Channel
