Golang 提供了包管理方式,方便项目的分类管理。
你可以理解为这是进阶版的 Get Start。
项目结构
flowchart TD
P("项目路径 - 项目名")
D1("包路径 - 包名")
D2("包路径 - 包名")
_1("...")
D0("包路径 src - 包名 main")
F11("源文件")
F12("源文件")
_2("...")
F21("源文件")
F22("源文件")
F23("源文件")
_3("...")
_4("...")
F01("源文件 main.go")
P --> D1 & D2 & _1 & D0
D1 --> F11 & F12 & _2
D2 --> F21 & F22 & F23 & _3
D0 --> _4 & F01
- 项目结构包括:
项目路径:项目目录在此电脑上的位置。项目名:go mod init时为项目命的名,与项目路径呈对应关系,通常与项目路径最后一级命名相同。包路径:导包时使用包路径,包是最后一级目录,包路径为标准库路径或项目名/包相对于项目路径。其中main 包路径应为项目名/src。包名:打包时定义包名,程序内使用包名区别各个包,与包路径呈对应关系,通常与包路径最后一级命名相同。其中main 包包名应为main。源文件:写有代码的.go文件,一个包可以有多个源文件,一个包内所有源文件的包名必须相同,不同包间所有源文件的包名必须不同。
新建项目、打包、导包
新建项目
- 如果一个项目涉及多个自定义包,应该新建项目。
- 在执行
go mod init命令后,项目目录下会生成go.mod文件,该目录下所有文件属于该项目。
cd {项目路径}
go mod init {项目名}
cd D:/Go/Project/Test
go mod init testProject
打包
- 所有文件必须打包,打包语句必须位于程序第一行。
main是特殊的包,main包必须包含main函数(main函数不能有任何参数和返回值),非main包不得包含main函数。
package <包名> // 一般以小写字母开头, 打包时定义包名
package main
导包
- 导包
import应该紧跟在打包语句后,注意导包时使用包路径而非包名。 - 如果导包使用别名,访问包内对象应使用别名;否则,访问包内对象应使用包名。
import "<包路径>" // 单个包导入
import (
"<包路径1>"
"<包路径2>"
...
) // 多个包导入
import <别名> "<包路径>" // 使用别名
import (
"fmt" // 标准库包
"testProject/packageDirectory1" // 自定义包
)
运行项目
cd {项目路径}/src
go build
./src.exe
全局作用域
-
直接定义在包中的函数、变量都是全局变量。
-
全局变量一旦被定义将始终存在,直到程序终止。
-
全局变量可以在包之间共享,它分为:
- 受保护(
Protected),所有内部包可以相互访问。所有小写字母开头的全局变量、函数是受保护的。 - 公有(
Public),允许外部包访问共有成员。所有大写字母开头的全局变量、函数是公有的。
- 受保护(
项目案例
- 注意:项目名通常与项目路径最后一级命名相同,包名通常与包路径最后一级命名相同。但在此案例中为了区分两者的区别,使用不同的命名。
新建项目
cd D:/Go/Project/TestProject
go mod init test
生成 go.mod 文件:
module test
go 1.20
构建项目结构
D:/Go/Project/TestProjectpackageDirectory1packageFile1.gopackageFile2.go
packageDirectory2packageFile3.gopackageFile4.go
srchello.gomain.go
编写源代码
./packageDirectory1/packageFile1.go
package packageName1
func Add(x, y int) int {
return x + y
}
func mul(x, y int) int {
return x * y
}
./packageDirectory1/packageFile2.go
package packageName1 // 同包不同源文件必须使用相同包名
func Mul(x, y int) int {
return mul(x, y) // 包内可直接访问受保护对象
}
./packageDirectory2/packageFile3.go
package packageName2 // 不同包的源文件间必须使用不同包名
func Sub(x, y int) int {
return x - y
}
./packageDirectory2/packageFile4.go
package packageName2
func Div(x, y int) int {
return x / y
}
./src/hello.go
package main
import "fmt"
func hello() {
fmt.Println("Hello World!")
}
./src/main.go
package main
import (
"fmt" // 标准库包
p1 "test/packageDirectory1" // 项目名/包路径
p2 "test/packageDirectory2"
)
func main() {
fmt.Println(p1.Add(3, 7))
fmt.Println(p1.Mul(3, 7)) // 包外只能访问公有对象, p1.mul(3, 7) 是错误的
fmt.Println(p2.Sub(3, 7))
fmt.Println(p2.Div(3, 7))
hello() // 包内访问不需要导包
}
编译并运行
cd D:/Go/Project/TestProject/src
go build
./src.exe
10
21
-4
0
Hello World!