Golang语言学习笔记(十)

Golang中的go mod以及Golang包详解

1.Golang中包的介绍和定义

包(package)是多个Go源码的集合,是一种高级的代码复用方案,Go语言为我们提供了很多内置包,如fmt,strconv,sort,errors,time,encoding/json,os,io等。

Golang中的包可以分为三种:1.系统内置包 2.自定义包 3.第三方包

系统内置包:Golang语言给我们提供的内置包,引入后可直接使用,如fmt,strconv,sort,errors,time,encoding/json,os,io等。

自定义包:开发者自己写的包

第三方包:属于自定义包的一种,需要下载安装到本地后才可以使用,如前面用到的"github.com/shopspring/decimal"包解决float精度丢失问题

2.Golang包管理工具 go mod

在Golnag 1.11 版本之前如果要自定义包,必须把项目放在GOPATH目录。Go1.11版本之后无需手动配置环境变量,使用go mod管理项目,也不需要非得把项目放到GOPATH指定目录下,可以再磁盘任意位置新建项目,Go1.13以后可以彻底不要GOPATH 了。

1.go mod init 初始化项目

实际项目开发中,首先在项目目录中用go mod命令生成一个go.mod文件管理项目的依赖。

比如我们的项目文件放在了Demo16这个文件夹,这个时候我们需要在Demo16文件夹里面使用go mod命令生成一个 go.mod文件

go mod init 项目名称

在Demo16下建calc文件夹,在calc文件夹下建calc.go文件

package calc

在Demo16下建main.go文件作为程序主入口,引入calc包
package main

import (
    "Demo16/calc"
    "fmt"
)

3.Golang中自定义包

包(package)是多个Go源码的集合,一个包可以简单理解为一个存放多个.go文件的文件夹。该文件夹下面的所有go文件都要在代码第一行添加如下代码,声明该文件归属的包。

package 包名

注意事项:

  • 一个文件夹下面直接包含的文件只能归属一个package,同样一个package的文件不能在多个文件夹下。
  • 包名可以不和文件夹名字一样,包名不能包含 - 符号
  • 包名为main的包为应用程序的入口包,这种包编译后会得到一个可执行的文件,而编译不包含main包的源代码则不会得到可执行的文件

1.定义一个包

如果想在一个包中引用另外一个包里的标识符(如变量,常量,类型,函数等)时,该标识符

2.导入一个包

单行导入
单行导入的格式如下:

import "包1"
import "包2"

多行导入
多行导入的格式如下:

import (
    "包1"
    "包2"
)

匿名导入包
如果只希望导入包,而不使用包内部的数据时,可以使用匿名导入包。具体的格式如下:

import _ "包的路径"

匿名导入的包与其他方式导入的包一样都会被编译到可执行文件中。

自定义包名

在导入包名的时候,可以为导入的包设置别名。通常用于导入的包名太长或者导入的包名存在冲突的情况。具体语法格式如下:

import 别名 "包的路径"

4.Golang中init()初始化函数

init()函数介绍
在Go语言程序执行时导入包语句会自动触发包内部init函数的调用。需要注意的是:init()函数没有参数也没有返回值。init()函数在程序运行时自动被调用执行,不能再代码中主动调用它。

包初始化执行的顺序如下图所示:

init函数执行顺序
Go语言包会从main包开始检查其导入的所有包,每个包中又可能导入了其他的包。Go编译器由此构建出一个树状的包引用关系,再根据引用顺序决定编译顺序,依次编译这些包的代码。

在运行时,被最后导入的包会最先初始化并调用其init()函数,如下图所示

5.Golang中使用第三方包

我们可以在 https://pkg.go.dev/ 查找常见的golang第三方包

1.找到需要下载安装的第三方包的地址

比如前面用到的解决float精度损失的包decimal
https://github.com/shopspring/decimal

2.安装包

第一种方法:go get 包名称 (全局)

go get github.com/shopspring/decimal

第二种方法:go mod download (全局)

go mod download

依赖包会自动下载到$GOPATH/pkg/mod,多个项目可以共享缓存的mod,注意使用go mod download的时候首先需要在项目里面引入第三方包

第三种方法: go mod vendor 将依赖复制到当前项目的vendor下 (本项目)

go mod vendor

注意:使用go mod vendor 的时候首先需要在项目里面引入第三方包

3.看文档使用包

包安装完毕后,可以看文档使用安装的包

代码:
Demo16/main.go

package main

import (
	// "Demo16/calc"
	"fmt"
	// "Demo16/tools"
	// T "Demo16/tools"//使用T作为tools包的别名
	// _ "Demo16/tools"
	// "github.com/shopspring/decimal"
)

//main包中init函数优先于main函数
func init() {
	fmt.Println("main init ...")
}
func main() {

	// sum := calc.Add(10, 2)
	// fmt.Println(sum)//12

	// fmt.Println(calc.Age)//公有变量
	// fmt.Println(calc.aaa)//cannot refer to unexported name calc.aaa

	//调用tools包里的方法
	// a := tools.Mul(2, 3)
	// fmt.Println(a)//6

	// tools.PrintInfo()//print information

	// tools.SortIntAsc()//按照升序对int切片排序
	//同一个包里不同文件下的方法不能重复

	// b := T.Mul(3,4)
	// fmt.Println(b)//12

	//测试init方法执行顺序
	// tools.PrintInformation()

	// quantity := decimal.NewFromInt(3)
	// fmt.Println(quantity)

}

Demo16/calc/calc.go

package calc

import "fmt"
var aaa = "私有变量"//首字母小写表示私有

var Age = "公有变量"

func init() {
	fmt.Println("calc init...")
}

func Add(x, y int) int  {//首字母大写,公有方法
	return x + y
}

func sub(x, y int) int  {//首字母小写,私有方法
	return x - y
}

Demo16/tools/tools.go

package tools

import "fmt"
import _ "Demo16/calc"

func init() {
	fmt.Println("tools init...")
}

func PrintInformation() {
	fmt.Println("tools print...")
}

Demo16/tools/calc.go

package tools

func Mul(x, y int) int {
	return x * y
}

Demo16/tools/sort.go

package tools

import "fmt"

func SortIntAsc()  {
	fmt.Println("按照升序对int切片排序")
}

Demo16/tools/test.go

package tools

import "fmt"

func PrintInfo()  {
	fmt.Println("print information")
}

func init() {
	fmt.Println("test init...")
}
原文地址:https://www.cnblogs.com/hanajiang/p/13804093.html