go开发需要了解的基本知识 - yellia1989/learn-doc GitHub Wiki
开发环境搭建
安装完go程序后,设置GOROOT和GOPATH(通过go env获取路径)。这样就可以开始开发了。注意,以后的开发就在GOPATH目录下进行。
go的包管理
module代表一个go功能(exe),它由许多个package组成。package中的所有文件中定义的变量,函数相互可见。一个项目中一般包含一个module,也可以包含多个。
go mod init
初始化一个module,生成一个go.mod文件,里面定义了module的module path(导入路径)和go版本号,module path标识了这个module的import path,package的import路径为module path+package name(文件夹名称)
使用package
mkdir morestrings
vim morestrings/reverse.go
// Package morestrings implements additional functions to manipulate UTF-8
// encoded strings, beyond what is provided in the standard "strings" package.
package morestrings
// ReverseRunes returns its argument string reversed rune-wise left to right.
func ReverseRunes(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}
vim main.go
import (
"fmt"
"github.com/user/hello/morestrings"
)
func main() {
fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
}
go build / go install
go build会在当前目录生成hello
go install则会在GOPATH/bin目录下生成hello
go get会下载module中用到的远程package
变量初始化顺序
在一个go文件中, 初始化顺序规则:
- 引入的包
- 当前包中的变量常量
- 当前包的init
- main函数
注意:
- 当前go源文件中, 每一个被Import的包, 按其在源文件中出现顺序初始化。
- 如果当前包有多个init在不同的源文件中, 则按源文件名以字典序从小到大排序,小的先被执行到, 同一包且同一源文件中的init,则按其出现在文件中的先后顺序依次初始化; 当前包的package level变量常量也遵循这个规则; 其实准确来说,应是按提交给编译器的源文件名顺序为准,只是在提交编译器之前, go命令行工具对源文件名按字典序排序了。
- init只可以由go runtine自已调用, 我们在代码中不可以显示调用,也不可以被引用,如赋给a function variable。
- 包A 引入包B , 包B又引入包C, 则包的初始化顺序为: C -> B -> A
- 引入包,必须避免死循环,如 A 引 B , B引C, C引A.
- 一个包被其它多个包引入,如A -> B ->C 和 H -> I -> C , C被其它包引了2次, 但是注意包C只被初始化一次。
- 另一个大原则, 被依赖的总是先被初始化,当然呀。
- main包总是被最后一个初始化,这很好理解,因为它总是依赖别的包。
变量短声明
- 通过 变量名:= 表达式 来声明变量
- 只能使用在函数内部
- 重复使用短变量声明时,需要保证短变量声明语句中至少要声明一个新的变量,否则直接使用赋值语句 = 就可以了
- 在不同的作用域(if,for,switch),短变量声明语句会重新声明新的变量
- 在不同的作用域中,重复使用短变量声明时,如果变量名相同,会重新声明新的变量。
package main
import (
"fmt"
"os"
)
func main() {
file, err := os.Open("file.go")
if err != nil {
file, err := os.Open("file2.go") // file 和 err 在 if 作用域中,是重新声明的两个变量
fmt.Println(&file, &err) // 通过两次输出的 file 和 err 的地址不同可以确认
}
fmt.Println(&file, &err)
}
类型转换
go是强类型语言,不能做像C/C++一样隐式的类型转换。