基础
环境搭建
下载安装包
下载完成后,可以使用 go version
查看版本信息。
$ go version
go version go1.15.6 darwin/amd64
环境变量
Go 语言中环境变量主要有两个:
GOROOT
:Go 语言的安装目录。GOROOT/src
目录下的函数都可以被导入和使用。例如fmt.Println
。GOPATH
:除了 Go 语言的安装目录外的源码目录,同样可以调用目录下的函数。
可以使用 go env
查看环境变量。
$ go env GOROOT
/usr/local/go
$ go env GOPATH
/Users/username/go
可以使用 export
命令设置环境变量。
$ export GOROOT=/usr/local/go
$ export GOPATH=/Users/username/go
IDE
通常使用 GoLand 进行开发。下载地址:GoLand (opens in a new tab)
Go 的跨平台
Java 一直遵循一次编译,到处运行的原则,虽然 Go 不是一次编译,到处运行的语言,但是能做到一次编写,到处运行。这是因为 Go 不像 Java 拥有自己的虚拟机,Go 语言的编译器会将 Go 代码编译成机器码,然后直接运行在操作系统上。虽然牺牲了一定的便利性,但是保障了性能。
Go 语言会区分运行程序的操作系统,主要通过操作系统和CPU 架构来区分。
$ go env GOOS
windows
$ go env GOARCH
amd64
常见的 Goos 和 Goarch 如下:
GOOS | GOARCH | 说明 |
---|---|---|
darwin | amd64 | Mac OS |
linux | amd64 | Linux |
windows | amd64 | Windows |
可以使用 go tool dist list
查看所有支持的操作系统和 CPU 架构。
$ go tool dist list
我们无需进行任何显式的操作,Go 语言会自动识别当前的操作系统和 CPU 架构,然后编译成对应的可执行文件。
不过当我们尝试在 MacOS 上编译 Windows 的可执行文件时,需要进行一些额外的操作。
$ export GOOS=windows GOARCH=amd64
$ go build hello.go
如果要恢复原来的运行状态,需要对这两个变量进行清空。
$ export GOOS= GOARCH=
编译执行过程
我们通过 go help build
查看编译命令的帮助信息。
$ go help build
- a
force rebuilding of packages that are already up-to-date.
- n
print the commands but do not run them.
...
有三个值得我们关注的参数:
-n
:打印编译的详细过程,但不执行。相当于预览。-x
:打印编译的详细过程,并执行。--work
:打印编译的详细过程,并且保留生成的中间文件和目录,方便我们进行调试。
$ go build -x hello.go
WORK=/var/folders/28/1z5z1j7d7zq7z1z7z1z7z1z7z1z7z1z/T/go-build1234567890
mkdir -p $WORK/b001/
cat >$WORK/b001/_gomod_.go << 'EOF' # internal
packagefile command-line-arguments=/Users/username/Libraries/Caches/go-build/12/34567890abcdefg
packagefile fmt=/usr/local/go/src/fmt.a
packagefile runtime=/usr/local/go/src/runtime.a
...
...
...
packagefile runtime=/usr/local/go/src/path.a
modinfo "0w\xaf\x1f\x.."
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/exe/hello -trimpath $WORK -p main -complete -buildid 1234567890abcdefg -D _/Users/username/Libraries/Caches/go-build -I $WORK/b001 -pack ./hello.go
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -L $WORK/b001 -extld=clang -buildmode=exe -buildid=1234567890abcdefg $WORK/b001/exe/hello
mv $WORK/b001/exe/a.out hello
快速开始
Hello World
$ mkdir hello
$ cd hello
$ go mod init hello
go: creating new go.mod: module hello
通过 go mod init
命令初始化一个新的模块,会在当前目录下生成一个 go.mod
文件,内容如下:
module hello
go 1.15
然后创建一个 hello.go
文件,内容如下:
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
运行 go run hello.go
,可以看到输出结果:
$ go run hello.go
Hello, World!
Main 函数
Go 程序的入口是 main
函数。
Go 程序执行时,将先从 fmt 包中导入 Println
函数以及其他的函数,并在 main 函数中调用。
编译
$ go build
$ ./hello
Hello, World!
这里 go build
命令会生成一个可执行文件,然后执行该文件。
在 Windows 系统下,会生成一个 hello.exe
文件,然后执行该文件。
注释和转义符
注释
Go 语言中的注释有两种,分别是单行注释和多行注释。
单行注释以 //
开头,多行注释以 /*
开头,以 */
结尾。
// 这是单行注释
/*
这是多行注释
*/
不过不推荐使用多行注释,Go 在源代码中均使用单行注释。
转义符
Go 语言中的转义符有以下几种:
转义符 | 含义 |
---|---|
\r | 回车符(返回行首) |
\n | 换行符(直接跳到下一行的同列位置) |
\t | 制表符 |
\\ | 反斜杠 |
\' | 单引号 |
\" | 双引号 |
转义符的使用十分麻烦,推荐使用后面的原义字符。
原义字符
类似于 JS 中的模板字符串,Go 语言中也有原义字符。
package main
import "fmt"
func main() {
a := `"hello
world"`
fmt.Println(a)
}
输出结果:
"hello
world"
Go 的分号
Go 语言中的语句结尾不需要分号,如果写了分号,编译器会自动忽略。
fmt 格式化字符
格式化字符 | 含义 |
---|---|
%v | 值的默认格式 |
%+v | 类似 %v,但输出结构体时会添加字段名 |
%#v | 值的 Go 语法表示 |
%T | 值的类型的 Go 语法表示 |
%% | 百分号 |
%b | 二进制表示 |
%c | 相应 Unicode 码点所表示的字符 |
%d | 十进制表示 |
%o | 八进制表示 |
%q | 单引号围绕的字符字面值,由 Go 语法安全地转义 |
%x | 十六进制表示,字母形式为小写 a-f |
%X | 十六进制表示,字母形式为大写 A-F |
%U | Unicode 格式:U+1234,等同于 "U+%04X" |
%e | 科学计数法表示 |
%E | 科学计数法表示 |
%f | 浮点数表示 |
%F | 等价于 %f |
%g | 根据情况选择 %e 或 %f 以产生更紧凑的(无末尾的 0)输出 |
%G | 根据情况选择 %E 或 %F 以产生更紧凑的(无末尾的 0)输出 |
%s | 字符串表示 |
运算符
算术运算符
运算符 | 含义 |
---|---|
+ | 相加 |
- | 相减 |
* | 相乘 |
/ | 相除 |
% | 求余 |
关系运算符
运算符 | 含义 |
---|---|
== | 相等 |
!= | 不等 |
> | 大于 |
< | 小于 |
>= | 大于等于 |
<= | 小于等于 |
逻辑运算符
运算符 | 含义 |
---|---|
&& | 逻辑与 |
` | |
! | 逻辑非 |
位运算符
运算符 | 含义 |
---|---|
& | 按位与 |
` | ` |
^ | 按位异或 |
<< | 左移 |
>> | 右移 |
赋值运算符
运算符 | 含义 |
---|---|
= | 简单赋值 |
+= | 相加后赋值 |
-= | 相减后赋值 |
*= | 相乘后赋值 |
/= | 相除后赋值 |
%= | 求余后赋值 |
<<= | 左移后赋值 |
>>= | 右移后赋值 |
&= | 按位与后赋值 |
|= | 按位或后赋值 |
^= | 按位异或后赋值 |
其他运算符
运算符 | 含义 |
---|---|
& | 取地址 |
* | 取指针的值 |
++ | 自增 |
-- | 自减 |
. | 结构体成员 |
命令行参数的接收
Go 中可以通过 os
包来接收命令行参数。
package main
import (
"fmt"
"os"
)
func main() {
for i, arg := range os.Args {
fmt.Printf("arg[%d]: %s\n", i, arg)
}
}
执行 go run main.go hello world
,可以看到输出结果:
arg[0]: /var/folders/28/1z5z1j7d7zq7z1z7z1z7z1z7z1z7z1z/T/go-build1234567890/b001/exe/main
arg[1]: hello
arg[2]: world
这是顺序获得命令行参数的方法,实际上还能通过参数名来获取参数。
package main
import (
"flag"
"fmt"
)
func main() {
var name = flag.String("name", "everyone", "The greeting object.") // 参数名,默认值,参数说明
flag.Parse() // 解析参数
fmt.Println("Hello, ", *name) // *name 表示获取 name 的值, 如果直接使用 name 会输出指针地址
}
执行 go run main.go -name=world
,可以看到输出结果:
Hello, world