Go语言--第8章 包(package)
2021-02-19 21:20
标签:str 声明 调用 com container -o ccf 程序 export GOPATH是go语言使用的一个环境 变量,使用绝对路径 显示go开发环境配置信息: GOPATH在不同平台上的安装路径 GOPATH工作目录下,代码保存在$GOPATH/src目录下 通过go build\go install\go get等命令,将产生二进制可执行文件放在\(GOPATG/bin目录**下,生成中间缓存文件保存放在**\)GOPATG/pkg目录下 若需要将整个源码添加到版本控制工具中,只需将$GOPATH/src目录源码添加即可 以下示例为linux平台操作 设置当前工作目录为GOPATH 例如: GOPATH="/Users/jihan/go" 建立GOPATH中源码目录 添加main.go源码文件 创建$GOPATH/src/main.go 编译源码并运行 编译完可执行文件会保存在$GOPATH/bin目录下 包要求在目录下的所有文件的第一行添加 特性: 如果一个包引用另一个包的标识符(类型、变量、 常量时)必须首先将被引用的标识符导出 将myStruct和myConst首字母大写,导出这些标识符 导出结构体及接口成员 结构体和接口成员同样字段或方法首字母大写,外部可以访问 使用import关键字,导入包包名使用双引号包围 单行导入 多行导入 导入包例子 importadd/mylib/add.go eight/8.4/main.go 格式 path/to/package 导入包路径 customName 自定义包名 特性:init()函数 每个源码可以食欲哦那个1个init()函数 init()会在程序执行前(main()函数执行前)被自动调用 调用顺序为main()中引用的包,以深度优先顺序初始化 例如:包引用关系 main -> A->B->C 调用顺序为:c.init->B.init->A.init->main 同一个包的多个init()函数调用顺序不可以预期 init()不能憋其他函数调用 go语言包会从main包开始检查其所有引用所有包,每个包也可能包含其他的包 go编译器由此构建一个树状的包引用关系,在根据引用顺序决定编译顺序,依次编译这些包的代码 在运行时,被最后导入的包会最先初始化并调用init()函数 例子: 文件目录: .../eight/8.4.5/pkginit/main.go .../eight/8.4.5/pkginit/pkg1/pkg1.go .../eight/8.4.5/pkginit/pkg2/pkg2.go 运行结果: pkg2 init 利用包init()函数特性,将cls1和cls2两个包注册到工厂,使用字符串创建这两个注册好的结构实例 $HOME:src目录路径 目录结构: $HOME/eight/8.5/clsfactory/base/factory.go $HOME/eight/8.5/clsfactory/cls1/reg.go $HOME/eight/8.5/clsfactory/cls2/reg.go $HOME/eight/8.5/clsfactory/main.go 运行结构: Class1 Go语言--第8章 包(package) 标签:str 声明 调用 com container -o ccf 程序 export 原文地址:https://www.cnblogs.com/smallyi/p/12684478.html第8章 包(package)
8.1 工作目录
8.1.1 命令行查看GOPATH信息
go env
$ go env
// 表示目标处理器架构
GOARCH="amd64"
//表示编译器和链接器的安装位置
GOBIN=""
GOCACHE="/Users/jihan/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
//目标操作系统
GOOS="darwin"
//当前工作目录
GOPATH="/Users/jihan/go"
GOPROXY=""
GORACE=""
//GO开发包安装目录
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/vm/zby04lq56tg1y08qs5c6kkq80000gn/T/go-build459742728=/tmp/go-build -gno-record-gcc-switches -fno-common"
平台
GOPATH默认值
举例
Window平台
%USERPROFILE%/go
C:\Users\用户名\go
Uninx平台
$HOME/go
/home/用户名/go
8.1.2 使用GOPATH的工程结构
8.1.3 设置和使用GOPATH
export GOPATH=path
export GOPATH=/Users/jihan/go
mkdir -p src/hello
package main
import "fmt"
func main() {
fmt.Println("hello")
}
go install hello
./hello //进行执行
8.2 创建包package -- 编写自己的代码扩展
package 包名
8.3 导出标识符 -- 让外部访问包的类型和值
package mypkg
var myVar = 100
const myConst = "go"
type myStruct struct {}
package mypkg
var MyVar = 100
const MyConst = "go"
type MyStruct struct {}
type MyStruct struct {
//包外可以访问的字段
ExportField int
}
8.4 导入包(import) -- 在代码中使用其他的代码
8.4.1默认导入写法
import "包1"
import "包2"
import (
"包1"
"包2"
)
package mylib
func Add(a, b int) int {
return a + b
}
package main
import (
// 文件目录相对GOPATH的相对路径
"../../eight/8.4/mylib"
"fmt"
)
func main() {
fmt.Println(mylib.Add(1, 2))
}
8.4.2 自定义命名导入包名
customName "path\to\package"
package main
import (
renameMylib "../../eight/8.4/mylib"
"fmt"
)
func main() {
fmt.Println(renameMylib.Add(1, 2))
}
8.4.3 匿名导入包 -- 只导入包但不适用包内类型和数值
package main
import (
_ "../../eight/8.4/mylib"
"fmt"
)
func main() {
// fmt.Println(renameMylib.Add(1, 2))
}
8.4.4 包在程序启动前的初始化入口:init
8.4.5 理解包导入后的init()函数初始化顺序
.../eight/8.4.5
.../eight/8.4.5/pkginit
.../eight/8.4.5/pkginit/pkg1
.../eight/8.4.5/pkginit/pkg1/pkg1.go
.../eight/8.4.5/pkginit/pkg2
.../eight/8.4.5/pkginit/pkg2/pkg2.go
.../eight/8.4.5/pkginit/main.go
package main
import (
"../../../eight/8.4.5/pkginit/pkg1"
)
func main() {
pkg1.ExecPkg1()
}
package pkg1
import(
"../../../../eight/8.4.5/pkginit/pkg2"
"fmt"
)
func ExecPkg1() {
fmt.Println("ExecPkg1")
pkg2.ExecPkg2()
}
func init() {
fmt.Println("pkg1 init")
}
package pkg2
import(
"fmt"
)
func ExecPkg2() {
fmt.Println("ExecPkg2")
}
func init() {
fmt.Println("pkg2 init")
}
pkg1 init
ExecPkg1
ExecPkg28.5 示例:工厂模式自动注册--管理过个包的结构体
$HOME/eight/8.5
$HOME/eight/8.5/clsfactory
$HOME/eight/8.5/clsfactory/base
$HOME/eight/8.5/clsfactory/base/factory.go
$HOME/eight/8.5/clsfactory/cls1
$HOME/eight/8.5/clsfactory/cls1/reg.go
$HOME/eight/8.5/clsfactory/cls2
$HOME/eight/8.5/clsfactory/cls2/reg.go
$HOME/eight/8.5/clsfactory/main.go
package base
// 类接口
type Class interface {
Do()
}
// 声明保存工厂信息变量
var (
factoryByName = make(map[string]func() Class)
)
// 注册一个类生成工厂
func Register(name string, factory func() Class) {
factoryByName[name] = factory
}
// 根据名称创建对应的类
func Create(name string) Class {
if f, ok := factoryByName[name]; ok {
return f()
} else {
panic("name not found")
}
}
package cls1
import (
"../../../../eight/8.5/clsfactory/base"
"fmt"
)
// 定义类1
type Class1 struct {
}
// 实现Class接口
func (c *Class1) Do() {
fmt.Println("Class1")
}
func init() {
// 在启动时注册类1的工厂
base.Register("Class1", func() base.Class {
return new (Class1)
})
}
package cls2
import (
"../../../../eight/8.5/clsfactory/base"
"fmt"
)
// 定义类2
type Class2 struct {
}
// 实现Class接口
func (c *Class2) Do() {
fmt.Println("Class2")
}
func init() {
// 在启动时注册类1的工厂
base.Register("Class2", func() base.Class {
return new (Class2)
})
}
package main
import(
"../../../eight/8.5/clsfactory/base"
_ "../../../eight/8.5/clsfactory/cls1"
_ "../../../eight/8.5/clsfactory/cls2"
)
func main() {
// 根据字符串动态创建一个Class1的实例
c1 := base.Create("Class1")
c1.Do()
// 根据字符串动态创建一个Class2的实例
c2 := base.Create("Class2")
c2.Do()
}
Class2