一架梯子,一头程序猿,仰望星空!

go语言包(package)


go语言中所有的代码都是在包中的,类似java中的包,c++中的名字空间,包主要用来解决命名冲突问题,在不同的包中存在同名的函数或者struct类型定义是不会冲突的。

1.主包

主包,就是程序的入口函数所在的包,包名叫做main,例子:

// 主包
package main

import "fmt"

// 入口函数
func main() {
    fmt.Println("程序入口")
}

go程序执行的时候,首先会找到main包,然后从main包里面找到main函数,执行main函数。

2.定义包

我们可以定义自己的包,通常情况,我们的包名是包所在路径的最后一个目录名,例如:service/order 路径,那么我们包名就是order

语法:

package 包名

例子:

文件:service/order/pay.go

package order

// 定义常量
// 支付宝支付类型
const ORDER_TYPE_ALIPAY  = 1

// 微信支付类型
const ORDER_TYPE_WECHAT  = 2

// 定义PayOrder结构体类型
type PayOrder struct {
    Id int
    Price float64
}

关于包的路径,前面搭建开发环境的时候提到GOPATH环境变量指向工作空间,go编译的时候会从$GOPATH/src目录开始搜索包,例如:

我们的项目名:tizi

项目所在目录是:$GOPATH/src/tizi

上面例子的包所在目录为:$GOPATH/src/tizi/service/order/

默认情况,只有这样组织项目和包的目录,才能找到包,否则会报错。

3.导入包

可以通过import导入包,有两种形式导入包:

导入单个包

import "包名"

导入多个包

import (
    "包名1"
    "包名2"
)

指定包的别名,如果存在两个名字一样的包,可以通过指定别名区分开来

import (
    别名 "包名1"
    "包名2"
)

例子:

package main

import (
        // 导入我们自定义的包order
	"tizi/service/order"
	"fmt"
)

func main() {
        // 使用order包中定义的结构体
	o := order.PayOrder{}
	o.Id = 100
	o.Price = 12.6

	fmt.Println(o)
}

4.引用包成员

通过包名和点( . ) 可以引用包里面定义的成员, 成员指的是包里面定义的函数、类型、变量、常量。

例子:

package main

import (
        // 导入我们自定义的包order
	"tizi/service/order"
	"fmt"
)

func main() {
	// 引用包中常量
	fmt.Println(order.ORDER_TYPE_ALIPAY)

	// 引用包中结构体
	o := order.PayOrder{}
	o.Id = 100
	o.Price = 12.6

	fmt.Println(o)
}

5.包成员的可见性

在go语言中没有类似public、private针对可见性定义的关键词,在日常开发中,我们肯定希望包中有些成员,外部可以引用,有些成员不允许外部引用。

在go语言中成员可见性是通过首字母大小写区分:

  • 首字母大写,代表public,外部可以引用
  • 首字母小写,代表private,外部不可以引用

这套根据首字母大小写区分可见性的规则,适用于包中的所有成员,包括结构体、结构体字段、函数、变量、常量。

例子:

package order

// 支付宝支付类型
const ORDER_TYPE_ALIPAY  = 1

// 微信支付类型
const ORDER_TYPE_WECHAT  = 2

// 定义PayOrder结构体类型
type PayOrder struct {
	Id int
	price float64  // 首字母小写,包外部无法访问这个字段
}

// 首字母小写,是私有方法,包外部无法引用
func getOrderInfoById(id int) {
	
}