包是Go程序的基本组织形式。包对应文件系统的目录,而包下存放着程序的源码文件。
源码文件又分为命令源码文件、库源码文件和测试源码文件三种。它们都有着不同的用途和编写规则。
包
代码包声明的基本规则
代码包声明的意思是指定源码文件属于哪个代码包。
规则1
同目录下的源码文件的代码包声明语句要一致。即它们要同属于一个代码包。
如果目录中有命令源码文件,那么其他种类的源码文件也应该声明属于main包。
规则2
源码文件声明的代码包的名称可以与其所在的目录的名称不同。在针对代码包进行构建时,生成的结果文件的主名称与其父目录的名称一致。
对于命令源码文件,构建生成的可执行文件的主名称会与其父目录的名称相同。
如果库源码文件声明的代码包名称与其父目录名称不相同。导入到命令源码文件时应该导入如父目录的相对路径(因为构建或安装后生成的归档文件名与其父目录名称一致),而使用此库文件中的程序实体时应该以库源码文件声明的代码包名称作为限定符。
例:
库源码文件 src/mytest/demo.go
package myte
import "fmt"
func Hello(){
fmt.Println("Hello World!")
}
注意:demo.go库源码文件在声明所属代码包时与其父目录名不一致。
命令源码文件 src/name.go
package main
import "mystest"
myte.Hello()
这里导入代码包时路径必须是库源码文件父目录名mytest
而调用库源码文件程序实体时包的限定符为myte
src下go run name.go 输出Hello xiaoming
虽然这样可以,但为了不产生迷惑,规范写法尽量把源码文件声明的包名跟其父目录同名
。
声明main包
你必须在源文件中非注释的第一行指明这个文件属于哪个包,如:package main。
package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。
源文件中非注释的第一行指明package main
package main
导入非main包
通过import关键字来导入其他非main包
import "fmt"
别名
可以给包名起别名如
import fm "fmt"
调用此包里的函数是就可以用fm这个别名来调用
导入多个包
import (
"fmt"
"os"
)
或者更简化写法
import("fmt";"os")
但这种写法在代码格式化的时候会自动格式化成上面那种多行形式
导入包即等同于包含了这个包的所有的代码对象。
包中对象被外部文件访问的规则
当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头
,那么使用这种形式的标识符的对象就可以被外部包的代码所使用
,这被称为导出
(像面向对象语言中的 public);
当标识符如果以小写字母开头
,则对包外是不可见的
,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 private )。
因此,在导入一个外部包后,能够且只能够访问该包中导出的对象。
Println() //大写字母开头的函数,可以访问
name //小写字母开头的变量,不可以访问
注意事项
导入了一个包必须使用它,这正是遵循了 Go 的格言:没有不必要的代码!
否则会在构建程序时引发错误,如
imported and not used: os
源码文件
命令源码文件
命令源码文件是程序的运行入口,是每个可独立运行的程序必须拥有的。可以通过构建或安装生成与其对应的可执行文件,可执行文件一般会与该命令源码文件的直接父目录同名。
如果一个源码文件声明属于main包,并且包含一个无参数声明且无结果返回的main函数,那么就是命令源码文件。
例:test.go
package main
import "fmt"
func main() {
fmt.Println("Hello World!")
}
命令行在命令源码文件所在的目录下,输入go run test.go
即可在屏幕输出Hello World!
通过构建或安装命令源码文件生成的可执行文件可以被视为是"命令"。如上例中在bin目录下生成的test就是一个命令
关于命令部分请参考Go编写命令一节的实例。
库源码文件
库源码文件用来存放程序实体,不能被直接运行。这些程序实体可以被其他代码使用。
在Go语言中,程序实体是变量、常量、函数、结构、接口的统称。实际中,先声明程序实体,再去使用。程序实体的名字统称为标识符。