首页 > Go 分布式学习利器(16) -- go中可复用的package构建

Go 分布式学习利器(16) -- go中可复用的package构建

通过本文,你将了解go 语言中如何将自己的package构建到项目中 以及如何将远程(github)的package构建到项目中。

1. 构建本地的package

  • package 是可复用模块的基本单元,以首字母大写的函数实现来表明可被包外代码访问
  • 代码的package可以和所在路径的代码不一致
  • 同一目录里的Go 代码的package 要保持一致

个人理解 本地包就像是C++/C中的头文件,其他代码只需要包含该头文件,即可使用头文件中生命的函数。

这里构建自己Go语言的package的时候需要注意代码路径,在环境中指定好的GOPATH路径中的src目录下创建自己实现的package目录。

比如指定~/.bashrc中:

export GOPATH="~/go/"

那么在该路径下的src目录创建自己的package目录即可,如下 series目录

在这里插入图片描述

实现series.go,同时在其他的package目录下的源码文件中import "ch11/series"即可使用series.go中实现的函数

ps : series.go中实现的函数名字开头需大写,这样是指定当前函数能够被在包外调用

其中 series.go实现代码如下:

package seriesimport "fmt"// 获取斐波那契数列,函数名必须大写,如果小写则在后面的包外调用中会报语法错
func GetFibList(n int) []int{ if n < 2 { return nil}if n > 100 { return nil}fibList := []int{ 1,1}for i := 2; i < n; i++ { fibList = append(fibList, fibList[i-1] + fibList[i-2])}return fibList
}

在ch11目录下的package_test目录创建一个package_test.go测试代码,调用series包中的函数

package package_testimport (fib "test/ch11/series" // 我的src目录下 是test/ch11/series"testing"
)func TestPackage(t *testing.T) { t.Log(fib.GetFibList(5))
}

最后成功运行,输出如下:

=== RUN   TestPackagepackage_test.go:9: [1 1 2 3 5]
--- PASS: TestPackage (0.00s)

2. 包内 初始化 init方法

GO支持初始化包的方法,且该方法有如下几个比较意思的特性

  • 在main被执行前,所有依赖的package的init方法都会被执行
  • 不同包的init函数按照包导入的依赖关系决定执行顺序

    比如pkg1 和 pkg2两个包,第一个包被先import的,那么pkg1的init函数会先执行
  • 每个包可以有多个init函数
  • 包的每个源文件也可以有多个init函数

比如之前的series包中,我们在series.go中加入两个init函数

package seriesimport "fmt"func init() { fmt.Println("first init")
}func init() { fmt.Println("second init")
}func GetFibList(n int) []int{  /* 两个返回值 */if n < 2 { return nil}if n > 100 { return nil}fibList := []int{ 1,1}for i := 2; i < n; i++ { fibList = append(fibList, fibList[i-1] + fibList[i-2])}return fibList
}

多个init在test文件中执行的时候会被先执行:

package package_testimport ("testing"fib "test/ch11/series"
)func TestPackage(t *testing.T) { t.Log(fib.GetFibList(5))
}

输出如下,可以看到series中的方法被调用时,init函数会优先其他所有调用者执行

first init
second init
=== RUN   TestPackagepackage_test.go:9: [1 1 2 3 5]
--- PASS: TestPackage (0.00s)
PASS

init函数有助于我们提前初始化好自己包内的一些资源

3. 构建远端的package

很多时候我们项目中需要一些开源的go框架:分布式协调服务etcd, 分布式通信go-grpc等,需要使用这一些开源代码中的package包,那么go语言提供了方便的获取方式,类似如下:

go get -u github.com/easierway/concurrent_map

指定的github的源码路径不需要加.git,以上命令会将http://github.com/easierway/concurrent_map.git中的master分支代码放入到GOPATH的src/github.com 路径下,并且不包含项目中的.git目录(不会随着社区更新)。

包含之后就可以直接使用该远程package了:

package remote_packageimport "testing"
import cm "github.com/easierway/concurrent_map" //导入远端下载下来的packagefunc TestConcurrentMap(t *testing.T) { m := cm.CreateConcurrentMap(99) // 调用包内的相关方法m.Set(cm.StrKey("key"),10)t.Log(m.Get(cm.StrKey("key")))
}

输出如下:

=== RUN   TestConcurrentMapremote_package_test.go:9: 10 true
--- PASS: TestConcurrentMap (0.00s)
PASS

更多相关:

  • 草色新雨中, 松声晚窗里。之前我们学习 Power Query 都是用鼠标就完成了很多复杂的操作。虽然 PowerQuery 已经将大部分常用功能内置成到功能区。基本能完成我们大部分的报表自动化功能。但是总有些复杂的或者个性化的问题是开发团队没有预先想到的,这时我们就需要学习 M 语言。一、M 语言在哪里?M语言的函数公式有三个地...

  • 前言从2020年3月份开始,计划写一系列文档--《小白从零开始学编程》,记录自己从0开始学习的一些东西。第一个系列:python,计划从安装、环境搭建、基本语法、到利用Django和Flask两个当前最热的web框架完成一个小的项目第二个系列:可能会选择Go语言,也可能会选择Vue.js。具体情况待定,拭目以待吧。。。基本概念表达式表...

  • 1.1函数1.1.1什么是函数函数就是程序实现模块化的基本单元,一般实现某一功能的集合。函数名:就相当于是程序代码集合的名称参数:就是函数运算时需要参与运算的值被称作为参数函数体:程序的某个功能,进行一系列的逻辑运算return 返回值:函数的返回值能表示函数的运行结果或运行状态。1.1.2函数的作用函数是组织好的,可重复使用的,用来...

  • 原标题:基于Python建立深度神经网络!你学会了嘛?图1 神经网络构造的例子(符号说明:上标[l]表示与第l层;上标(i)表示第i个例子;下标i表示矢量第i项)单层神经网络图2 单层神经网络示例神经元模型是先计算一个线性函数(z=Wx+b),接着再计算一个激活函数。一般来说,神经元模型的输出值是a=g(Wx+b),其中g是激活函数(...

  • 在学习MySQL的时候你会发现,它有非常多的函数,在学习的时候没有侧重。小编刚开始学习的时候也会有这个感觉。不过,经过一段时间的学习之后,小编发现尽管函数有很多,但是常用的却只有那几个。今天小编就把常用的函数汇总一下,为大家能够能好的学习MySQL中的函数。MySQL常使用的函数大概有四类。时间函数、数学函数、字符函数、控制函数。让我...