Go语言快速入门

通过简单的例子,来快速入门Go语言基础编程、语法等各种语言特性,主要面向新手级别的学习者。下面所有例子均来源于网络,看文需谨慎后果自负。

安装之前需要了解及新建几个必要的文件目录:

  • GOROOT 目录,该目录为解压压缩包所存放的目录。

(建议 linux 环境解压到 /usr/local 目录,windows 环境解压到 C:\ProgramFiles 目录)

  • 新建 GOPATH 目录,即为我们的“工作目录”,该目录可以有多个,建议只设置一个。
  • GOPATH 目录下新建 src 目录,该目录用于存放第三方库源码,以及存放我们的项目的源码。
  • GOPATH 目录下新建 bin 目录,该目录用于存放项目中所生成的可执行文件。
  • GOPATH 目录下新建 pkg 目录,该目录用于存放编译生成的库文件。

安装Go

CentOS7中通过yum安装

  1. # CentOS7 可以只用使用yum安装
  2. yum install golang

CentOS7中通过源码安装

  1. # 源码下载
  2. # 官网源码 https://golang.org/dl/ 需要翻墙
  3. wget https://storage.googleapis.com/golang/go1.9.darwin-amd64.pkg
  4. tar zxvf go1.8.linux-amd64.tar.gz -C /usr/local
  5. # 新建GOPATH目录
  6. mkdir -p $HOME/gopath

Mac中通过brew命令安装

使用home brew安装方便快捷安装Go,如果你想要在你的 Mac 系统上安装 Go,则必须使用 Intel 64 位处理器,Go 不支持 PowerPC 处理器。

  1. brew update && brew upgrade # 更新 Homebrew 的信息
  2. brew install git # 安装 git
  3. brew install go # 安装 go

Mac中通过源码安装

通过源代码编译安装的过程与环境变量的配置与在 Linux 系统非常相似,因此不再赘述。

注意事项:

在 Mac 系统下使用到的 C 工具链是 Xcode 的一部分,因此你需要通过安装 Xcode 来完成这些工具的安装。你并不需要安装完整的 Xcode,而只需要安装它的命令行工具部分。

环境变量配置

通过go env查看go的详细信息

  1. go env
  2. GOARCH="amd64"
  3. GOBIN=""
  4. GOEXE=""
  5. GOHOSTARCH="amd64"
  6. GOHOSTOS="darwin"
  7. GOOS="darwin"
  8. GOPATH="/Users/kenny/go"
  9. GORACE=""
  10. GOROOT="/usr/local/Cellar/go/1.9/libexec"
  11. GOTOOLDIR="/usr/local/Cellar/go/1.9/libexec/pkg/tool/darwin_amd64"
  12. GCCGO="gccgo"
  13. CC="clang"
  14. GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/j7/3xly5sk567s65ny5dnr__3b80000gn/T/go-build377856897=/tmp/go-build -gno-record-gcc-switches -fno-common"
  15. CXX="clang++"
  16. CGO_ENABLED="1"
  17. CGO_CFLAGS="-g -O2"
  18. CGO_CPPFLAGS=""
  19. CGO_CXXFLAGS="-g -O2"
  20. CGO_FFLAGS="-g -O2"
  21. CGO_LDFLAGS="-g -O2"
  22. PKG_CONFIG="pkg-config"

如果需要修改默认的环境变量配置修改 vim ~/.bash_profile 或者 vim ~/.zshrc

  1. #GOROOT
  2. # CentOS 中如下设置 GOROOT,看你安装的路径
  3. # export GOROOT=/usr/local/go
  4. # Mac OS 中通过命令行工具brew安装如下配置 GOROOT
  5. export GOROOT=/usr/local/Cellar/go/1.9/libexec
  6. #GOPATH root bin
  7. export GOBIN=$GOROOT/bin
  8. export PATH=$PATH:$GOBIN
  9. #GOPATH
  10. export GOPATH=$HOME/go
  11. #GOPATH bin
  12. export PATH=$PATH:$GOPATH/bin

使其立即生效

  1. source /etc/profile

标准命令详解

  1. go --help
  2. Go is a tool for managing Go source code.
  3. Go是用于管理Go源代码的工具。
  4. Usage用法:
  5. go command [arguments]
  6. The commands are:
  7. build 命令用于编译我们指定的源码文件或代码包以及它们的依赖包。
  8. -o 指定输出的文件名,可以带上路径,例如 go build -o a/b/c
  9. -i 安装相应的包,编译+go install
  10. -a 更新全部已经是最新的包的,但是对标准包不适用
  11. -n 把需要执行的编译命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的
  12. -p n 指定可以并行可运行的编译数目,默认是CPU数目
  13. -race 开启编译的时候自动检测数据竞争的情况,目前只支持64位的机器
  14. -v 打印出来我们正在编译的包名
  15. -work 打印出来编译时候的临时文件夹名称,并且如果已经存在的话就不要删除
  16. -x 打印出来执行的命令,其实就是和-n的结果类似,只是这个会执行
  17. -ccflags 'arg list' 传递参数给5c, 6c, 8c 调用
  18. -compiler name 指定相应的编译器,gccgo还是gc
  19. -gccgoflags 'arg list' 传递参数给gccgo编译连接调用
  20. -gcflags 'arg list' 传递参数给5g, 6g, 8g 调用
  21. -installsuffix suffix 为了和默认的安装包区别开来,采用这个前缀来重新安装那些依赖的包,-race的时候默认已经是-installsuffix race,大家可以通过-n命令来验证
  22. -ldflags 'flag list' 传递参数给5l, 6l, 8l 调用
  23. -tags 'tag list' 设置在编译的时候可以适配的那些tag,详细的tag限制参考里面的http://golang.org/pkg/go/build/
  24. clean 删除掉执行其它命令时产生的一些文件和目录。
  25. -i 清除关联的安装的包和可运行文件,也就是通过go install安装的文件
  26. -n 把需要执行的清除命令打印出来,但是不执行,这样就可以很容易的知道底层是如何运行的
  27. -r 循环的清除在import中引入的包
  28. -x 打印出来执行的详细命令,其实就是-n打印的执行版本
  29. doc 命令可以打印附于Go语言程序实体上的文档。
  30. env 用于打印Go语言的环境信息。
  31. bug 启动错误报告。
  32. fix 把指定代码包的所有Go语言源码文件中的旧版本代码修正为新版本的代码。
  33. fmt 在包源上运行gofmt
  34. -l 显示那些需要格式化的文件
  35. -w 把改写后的内容直接写入到文件中,而不是作为结果打印到标准输出。
  36. -r 添加形如“a[b:len(a)] -> a[b:]”的重写规则,方便我们做批量替换
  37. -s 简化文件中的代码
  38. -d 显示格式化前后的diff而不是写入文件,默认是false
  39. -e 打印所有的语法错误到标准输出。如果不使用此标记,则只会打印不同行的前10个错误。
  40. -cpuprofile 支持调试模式,写入相应的cpufile到指定的文件
  41. generate 通过处理源生成Go文件。
  42. get 下载或更新安装指定的代码包及其依赖包,并对它们进行编译和安装。
  43. -d 只下载不安装
  44. -f 只有在你包含了-u参数的时候才有效,不让-u去验证import中的每一个都已经获取了,这对于本地fork的包特别有用
  45. -fix 在获取源码之后先运行fix,然后再去做其他的事情
  46. -t 同时也下载需要为运行测试所需要的包
  47. -u 强制使用网络去更新包和它的依赖包
  48. -v 显示执行的命令
  49. install 用于编译并安装指定的代码包及它们的依赖包。
  50. list 列出指定的代码包的信息。
  51. run 命令可以编译并运行命令源码文件。
  52. test Go语言编写的程序进行测试。
  53. -bench regexp 执行相应的benchmarks,例如 -bench=.
  54. -cover 开启测试覆盖率
  55. -run regexp 只运行regexp匹配的函数,例如 -run=Array 那么就执行包含有Array开头的函数
  56. -v 显示测试的详细命令
  57. tool 运行指定的go工具
  58. go tool fix . 用来修复以前老版本的代码到新版本,例如go1之前老版本的代码转化到go1,例如API的变化
  59. go tool vet directory|files 用来分析当前目录的代码是否都是正确的代码,例如是不是调用fmt.Printf里面的参数不正确,例如函数里面提前return了然后出现了无用代码之类的。
  60. version 打印Go的版本信息
  61. vet 用于检查Go语言源码中静态错误的简单工具。
  62. Use "go help [command]" for more information about a command.
  63. Additional help topics:
  64. c calling between Go and C
  65. buildmode description of build modes
  66. filetype file types
  67. gopath GOPATH environment variable
  68. environment environment variables
  69. importpath import path syntax
  70. packages description of package lists
  71. testflag description of testing flags
  72. testfunc description of testing functions
  73. Use "go help [topic]" for more information about that topic.

其它命令

  1. cat $GOROOT/VERSION # 查看版本
  2. $GOROOT/src/all.bash # 测试用例正确

依赖管理工具

目前 Go 语言常用的依赖管理工具,有三个 godepvendordbvendor 是go 1.5 官方引入管理包依赖的方式,1.6正式引入。所以这里推荐是用vendor来管理你的依赖。

快速开始:

  1. # 设置你的项目
  2. cd "my project in GOPATH"
  3. govendor init
  4. # 将现有的GOPATH文件添加到vendor。
  5. govendor add +external
  6. # 查看你的工作。
  7. govendor list
  8. govendor sync # 从远程仓库拉取依赖
  9. govendor get # 像“go get”一样,但将依赖项复制到“vendor”文件夹中。
  10. # 看看什么是使用包
  11. govendor list -v fmt
  12. # 指定要获取的特定版本或修订版本
  13. govendor fetch golang.org/x/net/context@a4bbce9fcae005b22ae5443f6af064d80a6f5a55
  14. govendor fetch golang.org/x/net/context@v1 # Get latest v1.*.* tag or branch.
  15. govendor fetch golang.org/x/net/context@=v1 # Get the tag or branch named "v1".
  16. # 给予任何先前版本的约束,将包更新为最新
  17. govendor fetch golang.org/x/net/context
  18. # 仅格式化您的存储库
  19. govendor fmt +local
  20. # 构建您的存储库中的所有内容
  21. govendor install +local
  22. # 仅测试您的存储库
  23. govendor test +local

运行Go

运行Go文档,在线预览文档

  1. # 如果你的 godoc 命令不存在,运行它安装
  2. $ go get -v golang.org/x/tools/cmd/godoc
  3. $ godoc -http=:6060
  4. # 运行上面一条命令,可访问文档http://localhost:6060/

通过go命令运行

我们先写一段GO代码,很简单就是打印输出一个hello world!, 保存为hello.go文件

  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("Hello, World!")
  5. }

命令运行go程序,在hello.go这个当前目录下运行下面命令,可以输出hello world!

  1. go run hello.go

通过go命令编译运行

GO程序的代码是可以直接编译成exe文件 或者 二进制文件直接运行,在hello.go目录下运行下面命令,即可把go程序编译成二进制文件

  1. go build hello.go

上面命令文件可以编译成一个hello可执行文件,然后直接在当前目录下 ./hello 运行,可以输出hello world!

在浏览器中运行

Go Playground 允许在浏览器里面编辑运行 Go 语言代码。在浏览器中打开 https://play.golang.org/ (需要穿越才能打开) ,输入代码,点击 Run,看看会发生什么?还有个 Share 按钮,点击它会得到一个用于分享的网址,任何人都能代开这个链接,试一试 https://play.golang.org/p/UIOwu0DBQV

格式化输入输出

输入输出语法方法

%[标记][宽度][.精度][arg索引]动词Print(arg列表)Println(arg列表)Printf(格式字符串, arg列表)

  1. package main
  2. import (
  3. "fmt"
  4. "time"
  5. )
  6. func main() {
  7. fmt.Println("Hello World!")
  8. fmt.Println("The time is", time.Now())
  9. }

标记

  1. + 总打印数值的正负号;对于%q(%+q)保证只输出ASCII编码的字符。
  2. - 在右侧而非左侧填充空格(左对齐该区域)
  3. # 备用格式:为八进制添加前导 0(%#o),为十六进制添加前导 0x(%#x)或
  4. 0X(%#X),为 %p(%#p)去掉前导 0x;对于 %q,若 strconv.CanBackquote
  5. 返回 true,就会打印原始(即反引号围绕的)字符串;如果是可打印字符,
  6. %U(%#U)会写出该字符的Unicode编码形式(如字符 x 会被打印成 U+0078 'x')。
  7. ' ' (空格)为数值中省略的正负号留出空白(% d);
  8. 以十六进制(% x, % X)打印字符串或切片时,在字节之间用空格隔开
  9. 0 填充前导的0而非空格;对于数字,这会将填充移到正负号之后
  • 其中 0- 不能同时使用,优先使用 - 而忽略 0
  • 标记有事会被占位符忽略,所以不要指望它们。例如十进制没有备用格式,因此 %#d%d 的行为相同。宽度和精度

[宽度][.精度]都可以写成以下三种形式:数值arg索引

  • 数值 表示使用指定的数值作为宽度值或精度值
  • * 表示使用当前正在处理的 arg 的值作为宽度值或精度值,如果这样的话,要格式化的 arg 将自动跳转到下一个。
  • arg索引* 表示使用指定 arg 的值作为宽度值或精度值,如果这样的话,要格式化的 arg 将自动跳转到指定 arg 的下一个。注意事项:

  • 宽度值:用于设置最小宽度。

  • 精度值:对于浮点型,用于控制小数位数,对于字符串或字节数组,用于控制字符数量(不是字节数量)。
  • 对于浮点型而言,动词 g/G 的精度值比较特殊,在适当的情况下,g/G 会设置总有效数字,而不是小数位数。arg 索引

由中括号和 arg 序号组成(就像这个实例"abc%+ #8.3[3]vdef"中的[3]),用于指定当前要处理的 arg 的序号,序号从 1 开始:'[' + arg序号 + ']'

动词/通用动词

  • v:默认格式,不同类型的默认格式如下:

布尔型:t整 型:d浮点型:g复数型:g字符串:s通 道:p指 针:p

  • #v:默认格式,以符合 Go 语法的方式输出。特殊类型的 Go 语法格式如下:

无符号整型:x

  • T:输出 arg 的类型而不是值(使用 Go 语法格式)。注意事项:动词不能省略,不同的数据类型支持的动词不一样。

布尔型

-t :输出 true 或 false 字符串。

整型

  • b/o/d:输出 2/8/10 进制格式
  • x/X:输出 16 进制格式(小写/大写)
  • c:输出数值所表示的 Unicode 字符
  • q:输出数值所表示的 Unicode 字符(带单引号)。对于无法显示的字符,将输出其转义字符。
  • U:输出 Unicode 码点(例如 U+1234,等同于字符串 “U+%04X” 的显示结果)对于 o/x/X:

  • 如果使用 “#” 标记,则会添加前导 0 或 0x。对于 U:

  • 如果使用 “#” 标记,则会在 Unicode 码点后面添加相应的 ‘字符’(前提是该字符必须可显示)浮点型和复数型

  • b:科学计数法(以 2 为底)

  • e/E:科学计数法(以 10 为底,小写 e/大写 E)
  • f/F:普通小数格式(两者无区别)
  • g/G:大指数(指数 >= 6)使用 %e/%E,其它情况使用 %f/%F字符串或字节切片

  • s :普通字符串

  • q :双引号引起来的 Go 语法字符串
  • x/X:十六进制编码(小写/大写,以字节为元素进行编码,而不是字符)对于 q:

  • 如果使用了 + 标记,则将所有非 ASCII 字符都进行转义处理。

  • 如果使用了 # 标记,则输出反引号引起来的字符串(前提是
  • 字符串中不包含任何制表符以外的控制字符,否则忽略 # 标记)对于 x/X:

  • 如果使用了 “ “ 标记,则在每个元素之间添加空格。

  • 如果使用了 “#” 标记,则在十六进制格式之前添加 0x 前缀。指针类型

  • p :带 0x 前缀的十六进制地址值。

  • #p:不带 0x 前缀的十六进制地址值。
  • Go 没有指针运算。Go 具有指针。 指针保存了变量的内存地址。

类型 *T 是指向类型 T 的值的指针。其零值是 nil 。

  1. var p *int

& 符号会生成一个指向其作用对象的指针。

  1. i := 42
  2. p = &i
  • 符号表示指针指向的底层的值。
  1. fmt.Println(*p) // 通过指针 p 读取 i
  2. *p = 21 // 通过指针 p 设置 i

这也就是通常所说的“间接引用”或“非直接引用”。

  1. package main
  2. import "fmt"
  3. func main() {
  4. i, j := 42, 2701
  5. p := &i // 指向我 i
  6. fmt.Println(*p) // 通过指针读 i
  7. *p = 21 // 通过指针设置 i
  8. fmt.Println(i) // 看到i的新值
  9. p = &j // 指向我 j
  10. *p = *p / 37 // 通过指针划分 j
  11. fmt.Println(j) // 看到j的新值
  12. }

符合类型

复合类型将使用不同的格式输出,格式如下:

  1. 结 构 体:{字段1 字段2 ...}
  2. 数组或切片:[元素0 元素1 ...]
  3. 映   射:map[键1:值1 2:值2 ...]

指向符合元素的指针:&{}, &[], &map[]复合类型本身没有动词,动词将应用到复合类型的元素上。结构体可以使用 “+v” 同时输出字段名。

格式化输入

  1. // 格式化输入:从输入端读取字符串(以空白分隔的值的序列),
  2. // 并解析为具体的值存入相应的 arg 中,arg 必须是变量地址。
  3. // 字符串中的连续空白视为单个空白,换行符根据不同情况处理。
  4. // \r\n 被当做 \n 处理。
  5. // 以动词 v 解析字符串,换行视为空白
  6. Scan(arg列表)
  7. // 以动词 v 解析字符串,换行结束解析
  8. Scanln(arg列表)
  9. // 根据格式字符串中指定的格式解析字符串
  10. // 格式字符串中的换行符必须和输入端的换行符相匹配。
  11. Scanf(格式字符串, arg列表)
  12. // Scan 类函数会返回已处理的 arg 数量和遇到的错误信息。

编程基础

内置关键字

  1. break default func interface select
  2. case defer go map struct
  3. chan else goto package switch
  4. const fallthrough if range type
  5. continue for import retrun var

预定义标识符

  1. append bool byte cap close complex complex64 complex128 uint16
  2. copy false float32 float64 imag int int8 int16 uint32
  3. int32 int64 iota len make new nil panic uint64
  4. print println real recover string true uint uint8 uintptr

行分隔符

  • 在 Go 程序中,一行代表一个语句结束,不需要分隔符。
  • 打算将多个语句写在同一行,它们则必须使用 ; 人为区分,并不鼓励这种做法。注释方法
  1. // 单行注释
  2. /*
  3. 多行注释
  4. */

标识符

  • 标识符用来命名变量、类型等程序实体。
  • 第一个字符必须是字母或下划线而不能是数字有效标识符
  1. mahesh kumar abc move_name a_123
  2. myname50 _temp j a23b9 retVal

无效标识符

  1. 1ab #(以数字开头)
  2. case #(Go 语言的关键字)
  3. a+b #(运算符是不允许的)

包引用 import

  1. import "fmt"
  2. import "os"
  3. import "io"

简写方式如下

  1. import (
  2. "fmt"
  3. "os"
  4. "io"
  5. )

包引用介绍

  1. .
  2. ├── cal
  3. ├── add.go
  4. ├── multi
  5. └── multiply.go
  6. └── subtract.go
  7. └── main.go

注意:package-demo 文件夹复制到 $GOPATH/src/ 目录下,不然运行报错哦

  1. go run $GOPATH/src/package-demo/main.go

main.go中如何调用add.go、subtract.go或者是multiply.go文件中的函数。

add.gosubtract.go文件中,包名为cal package calmultiply.go在 multi 文件夹下,所以程序的包名为multi package multi如果 mian 函数要调用add.go或者subtract.go中的函数,必须要引入包”cal” import "package-demo/cal"要调用multiply.go中的函数,必须要引入包”multi”,import "package-demo/cal/multi"Go中如果函数名的首字母大写,表示该函数是公有的,可以被其他程序调用,如果首字母小写,该函数就是是私有的

包别名

  1. import(
  2. ff "fmt"
  3. )
  4. // 或者
  5. import ff "fmt"
  6. // 别名包调用
  7. ff.Println('Hello World!')

省略调用

  1. import(
  2. . "fmt"
  3. )
  4. func main() {
  5. // 省略调用
  6. Println('Hello World!')
  7. }

可见性规则

Go语言中约定使用 大小写 来决定常量、变量、类型、接口、结构或函数是否可以被外部包所调用

  • 函数名字首字母 小写 即为 private 私有的
  • 函数名字首字母 大写 即为 public 公有