Golang变量常量、命令、init函数和mian函数-Golang夯实基础第二天
-
init
函数-
功能
在程序执行之前(调用
main
函数之前,做一些初始化的操作) -
特点
-
每个包可以可以有多个
init
函数;a.go
package main func init() { fmt.Println("我是来自a.go的init函数") }
b.go
package main func init() { fmt.Println("我是来自b.go的init函数") }
-
每个源文件可以有多个
init
函数;package main func init() { fmt.Println("我是init函数A") } func init() { fmt.Println("我是init函数B") } func init() { fmt.Println("我是init函数C") }
-
同一个包,
init
函数的执行顺序是官方没有说明; -
总体执行顺序:变量初始化->init()->main()
-
不能被其他函数调用
会显示函数undefined
-
-
执行顺序
- 对同一个go文件的
init()
调用顺序是从上到下的。 - 对同一个package中不同文件是按文件名字符串比较“从小到大”顺序调用各文件中的
init()
函数。 - 对于不同的
package
,如果不相互依赖的话,按照main包中"先import
的后调用"的顺序调用其包中的init()
,如果package
存在依赖,则先调用最早被依赖的package
中的init()
,最后调用main
函数。 - 如果
init
函数中使用了println()
或者print()
你会发现在执行过程中这两个不会按照你想象中的顺序执行。这两个函数官方只推荐在测试环境中使用,对于正式环境不要使用。
- 对同一个go文件的
-
-
变量初始化
golang
的变量初始化不是从上到下的初始化的,而是先从没有依赖其他变量的变量开始初始化的。-
案例一
package main import "fmt" var ( a = c + 1 b = a + 666 c = getC() ) func getC() int { return 9 } func main() { fmt.Println("a:", a, ",b:", b, ",c:", c) }
-
案例二
a.go
package deep import "fmt" var ( X int = Y + 9 Y int = Z + 66 ) func init() { fmt.Println("我是a.go的init函数") }
b.go
package deep import "fmt" var ( Z int = GetZ() ) func init() { fmt.Println("我是b.go的init函数") }
c.go
package deep import "fmt" func GetZ() int { fmt.Println("我是c.go的GetZ函数") return 3 } func init() { fmt.Println("我是c.go的init函数") }
d.go
package deep import "fmt" var ( W int = 666 ) func init() { fmt.Println("我是d.go的init函数") }
print.go
package deep import "fmt" func init() { fmt.Println("我是print.go的init函数") } func MyPrint() { fmt.Println("x:", X, ",y:", Y, ",z:", Z, ",w:", W) }
deep_test.go
package deep import "testing" func TestRun(t *testing.T) { MyPrint() }
-
案例三(失败案例)
x.go
package deep import "fmt" var ( A = B + 1 B = C + 66 ) func init() { fmt.Println("我是x.go的init函数") }
y.go
package deep import "fmt" var ( C = GetC() ) func GetC() int { return A } func init() { fmt.Println("我是y.go的init函数") }
deep_test.go
package deep import ( "fmt" "testing" ) func TestRun(t *testing.T) { // MyPrint() fmt.Println("A:", A, ",B:", B, ",C:", C) }
-
-
main
函数Go程序的默认入口函数
-
命令
# go Go is a tool for managing Go source code. Usage: go <command> [arguments] The commands are: bug start a bug report build compile packages and dependencies clean remove object files and cached files doc show documentation for package or symbol env print Go environment information fix update packages to use new APIs fmt gofmt (reformat) package sources generate generate Go files by processing source get add dependencies to current module and install them install compile and install packages and dependencies list list packages or modules mod module maintenance work workspace maintenance run compile and run Go program test test packages tool run specified go tool version print Go version vet report likely mistakes in packages Use "go help <command>" for more information about a command. Additional help topics: buildconstraint build constraints buildmode build modes c calling between Go and C cache build and test caching environment environment variables filetype file types go.mod the go.mod file gopath GOPATH environment variable gopath-get legacy GOPATH go get goproxy module proxy protocol importpath import path syntax modules modules, module versions, and more module-get module-aware go get module-auth module authentication using go.sum packages package lists and patterns private configuration for downloading non-public code testflag testing flags testfunc testing functions vcs controlling version control with GOVCS Use "go help <topic>" for more information about that topic.
-
go env
查看当前环境信息
go env -w Name=Value
修改配置信息 -
go run
编译并且运行程序
go run main.go
-
go build
编译
go build -o server server.go main.go
-
go get
下载或者更新依赖
-
go install
下载并且安装依赖
go get
和go install
的区别命令 功能 下载位置 生成文件位置 编译效果 应用场景 go get
从远程代码库中下载或更新 Go 代码包 $GOPATH/src $GOPATH/bin 可能由于版本或编译环境的不同,生成的可执行文件无法运行或出现其他问题 需要快速下载和安装指定版本的 Go 代码包,如果生成的可执行文件无法运行,则需要使用 go install 命令重新编译 go install
编译并安装 Go 代码包 无需下载自身代码,$GOPATH/src 用于依赖包的查找 GOPATH/bin或GOPATH/pkg 在当前环境下重新编译源代码并生成可执行文件或库,能够更加稳定地运行代码包 生成可执行文件或库,能够更加稳定地运行代码包 可以认为
go get
命令包含了go install
命令的部分功能,但是在一些特殊情况下,还是需要使用go install
命令来进行更灵活的编译和安装操作。使用
go install
之前需要先go get
-
-
下划线
_
匿名变量,用于忽略结果,无法访问,不占用命名空间,不会分配内存比如当函数返回值有两个,而其中一个没有作用,就可以使用这个
func AllAddOne(a, b int) (x, y int) { x = a + 1 y = b + 1 return } func Test_(t *testing.T) { _, res := AllAddOne(88, 99) fmt.Println(res) }
_
还可以用于一种特殊用途,当只想让某个包的init
运行,而不想让整个包都导入,就可以使用匿名变量,import _ "hello"
-
变量
-
常量
-
特点
- 无法修改,固定不变的值
- 使用
const
关键字定义 - 在初始化定义时就必须赋值
-
批量声明
const ( A = 100 B = 101 C = 102 ) const ( X = 200 Y Z )
这样子有规律的常量一个一个声明影响效率,Go为多常量声明提供了一个计数器
iota
(只能用于const
),让iota
关键字相当于一个变量,然后使用表达式进行赋值,第一个值为0const ( A = 100 + iota B C ) const ( X = iota*2 + 10 Y Z = 111//这里被打断了,后面的M也是111 M N = iota O _ _ P ) func TestConst(t *testing.T) { fmt.Println("A:", A, ",B:", B, ",C:", C, ",\nX:", X, ",Y:", Y, ",Z:", Z, ",\nM:", M, ",N:", N, ",O:", O, ",P:", P) }
使用单行多变量定义时,相同一行
iota
相同const ( A1, A2 = iota*2 + 1, iota*3 + 2 B1, B2 C1, C2 ) func TestConst(t *testing.T) { fmt.Println("A1:", A1, "A2:", A2, "\n", "B1:", B1, "B2:", B2, "\n", "C1:", C1, "C2:", C2) }
-
-
学习中遇到的问题及解决
-
参考链接
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。