Go语言-第一个程序和Go tools (fmt, run, build, install)

1. 初步使用

1.1 Go工具

常用的Go工具只有不多的几个命令:

  • go fmt
  • go run
  • go build
  • go install

Go语言有自己的严格的格式,一个好习惯是在提交代码前先用内置的格式调整程序调整一下格式:

go fmt
go fmt xxx.go
go fmt xxx

最简单的情况,就在.go文件所在目录下运行上述命令,那么当前目录下所有的.go文件就都处理了。
可以带参数指定目标文件或者目标包,只要GOPATH设定的没问题,能够找到包,这个命令就可以成功运行,统一格式我还是赞同的,起码阅读代码会有比较统一的体验。

本地试运行、调试,用:

go run xxx.go
go run *.go

注意:以上.go源文件必须包含带有main函数的那个.go源文件,只有其他的.go源文件是不能运行的。

编译成本地可执行文件:

go build xxx.go
go build xxx
go build

然后可执行文件可以直接运行。如果不指定文件,那么当前文件夹内含有main函数的.go源文件编译,然后生成一个跟目录名称一样的可执行文件。注意如果指定xxx.go,那么也是含有main函数的那个.go文件。

编译成成可发布的可执行文件:

go install xxx
go install

1.2 实例

1.2.1 工程结构

go项目结构一般如下,注意包名就是src下的目录名,包名需要全部小写字母组成,文件名与包名无要求,同一个包可以有多个go文件:

.
└── src
    ├── test
    │   ├── 1.go
    │   └── 2.go
    └── tmplib
        ├── lib1.go
        └── lib2.go

以上项目的应用程序名称是test,本地自定义包tmplib
test包含2个源文件,1.go和2.go;tmplib包含2个源文件lib1.go和lib2.go。

包名等于目录名,所以tmplib里的源文件应该属于tmplib包;但是test目录下的源文件不属于test包,而是main包,因为每个go程序必须有一个main包,程序的入口在其中的main函数。
详见每个源文件的第一行 package xxx

源文件清单:

//1.go
package main

import (
	"fmt"
	"tmplib"
)

func main() {
	fmt.Println("hello1")
	tmplib.Lib1()
	funcIn2()
}

//2.go
package main

import (
	"fmt"
	"tmplib"
)

func funcIn2() {
	fmt.Println("hello2")
	tmplib.Lib2("funcIn2")
}

//lib1.go
package tmplib

import (
    "fmt"
)

func Lib1() {
    fmt.Println("lib1")
}

//lib2.go
package tmplib

import (
    "fmt"
)

func Lib2(caller string) {
    fmt.Println("lib2:", caller)
}

想要构建运行应用程序test,首先要设置好环境变量,切换到src上一级目录,然后

export GOPATH=${PWD}

1.2.2 go fmt

见2.1节,go fmt可以指定单个.go文件,也可以指定一批.go文件,可以不指定,默认当前目录下的所有.go文件。
比如在/src/test目录下:

$go fmt
1.go
2.go

这样源文件的格式就已经用工具调整好了。

1.2.3 go run

本地调试运行go程序,最常用的是go run,见2.1节,通常需要包含main包里的所有文件,在/src/test目录下:

$go run *.go
hello1
lib1
hello2
lib2: funcIn2

如果指定的go文件不足,会发生找不到symbol的错误:

$go run 1.go
# command-line-arguments
./1.go:11:2: undefined: funcIn2

如果指定的go文件不包含入口main函数,也会报错:

$go run 2.go
# command-line-arguments
runtime.main_main·f: relocation target main.main not defined
runtime.main_main·f: undefined: "main.main"

如果不是在main包里,会报错并提示,需要在main包里,比如在tmplib目中运行:

$go run *.go
go run: cannot run non-main package

1.2.4 go build

go build会编译并在当前目录生成可执行文件,但是一般我不这么用,因为如果go run没啥问题了,那么go install也不应该有什么问题。
如果还有问题,通过go build 也不会发现。
而且这样生成的可执行文件,目录位置取决于当前的目录位置${PWD},也并不方便。不如按照固定的目录比如 /bin/xxx 规范。
在main包(./src/test)所在目录下build:

$go build *.go
$ls -l
-rwxrwxr-x 1 docker docker 1864476 Dec 11 14:51 1
-rw-rw-r-- 1 docker docker     108 Dec 11 14:29 1.go
-rw-rw-r-- 1 docker docker     109 Dec 11 14:29 2.go

生成了一个可执行文件1

在任意目录build(比如切换到./src同级目录):

$go build test
$ls -l
drwxrwxr-x 4 docker docker    4096 Dec 11 14:53 src
-rwxrwxr-x 1 docker docker 1864476 Dec 11 14:53 test

生成可执行文件test

1.2.5 go install

程序编写和调试之后,用go install发布。
go install对于main包和其他包的处理是不同的,main包会在src同级目录创建./bin目录,放入可执行文件;非main包会在src同级创建pkg目录,放入编译好的.a文件。
在任意目录中执行命令:

go install test

生成可执行文件及其依赖的包:

.
├── bin
│   └── test
├── pkg
│   └── linux_amd64
│       └── tmplib.a
└── src

把bin目录部署到生产环境即可,不会再依赖其他的部分了,这真是极好的。

你可能感兴趣的:(Go语言)