Skip to main content

Go 语言简介

wKevin

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

  • 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 -reload
    • http://localhost:8080/

Book

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:
      • go
        • env print Go environment information —— 查看 GO 环境变量
          • go help env
            • go env -json json 格式给出变量
            • go env -w NAME=VALUE 设置变量的默认值
            • go env -u NAME 恢复变量默认值
          • 变量:
            • GOROOT: go 官方版本的位置
            • GOPATH:go 工作环境的位置
              • go env -w GOPATH=$HOME/go
              • vi ~/.bash_profile & export GOPATH=$HOME/go
              • export PATH=$PATH:$(go env GOPATH)/bin:$HOME/.local/bin/
        • get download and install packages and dependencies —— 安装到 GOPATH
        • build compile packages and dependencies
          • go build [xxx.go] 生成一个本地可执行的文件
            • 不带源码生成的可执行文件名字就是代码里面 package name
            • 有带源码生成的可执行文件名字是 xxx 文件名
        • install compile and install packages and dependencies
        • run compile and run Go program
          • go run [-n] xxx.go 命令行运行 go 源码,分 2 步(-n可打印出来)
            • $GOROOT/pkg/tool/linux_amd64/compile 编译成 a
            • $GOROOT/pkg/tool/linux_amd64/link 链接、执行 a
        • clean remove object files and cached files
        • doc show documentation for package or symbol
        • bug start a bug report
        • fix update packages to use new APIs
        • fmt gofmt (reformat) package sources
        • generate generate Go files by processing source
        • list list packages
        • test test packages
        • tool run specified go tool
        • version print Go version
        • vet report 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.gz
  • tar -xvf go1.13.4.linux-amd64.tar.gz
  • sudo mv go /usr/local or sudo 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

  1. go get golang.org/x/tools —— 被墙
  2. go get github.com/golang/tools
  3. cd $GOPATH/src/golang.org/x -- git clone https://github.com/golang/tools.git -- go get golang.org/x/tools
  4. cd $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

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.dev
    • export 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

公司的 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 先查看一下当前的安装目录,默认在 ~/go
  • mkdir -p ~/workspace/go
  • cd ~/workspace/go
  • export GOPATH=$(pwd) 更改 GOPATH ,注意仅限于本次

Build

gc

gccgo

Debug

gdb

delve

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
    • ./configure
    • make -j8
    • sudo make install
    • sudo ldconfig libzmq 安装在 /usr/local/lib 下,此命令刷新 /etc/ld.so.cache~ 缓存, gophernotes 才能找到 libzmq
  • 安装 gophernotes
    • go get -u github.com/gopherdata/gophernotes
    • mkdir -p ~/.local/share/jupyter/kernels/gophernotes
    • cp $(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)/src
      • mkdir -p golang.org/x
      • cd golang.org/x
      • git clone https://github.com/golang/tools.git

Atom + Go-Plus

Sublime Text + GoSublime

VIM + Vim-Go

IDE

GoLand(jetbrains)

Komodo

LiteIDE

Eclipse + GoClipse

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

Go 框架