在 《go 项目结构》 一文我们就已经学会了如何声明一个包了。现在我们再加一点新的知识——包初始化。

1. init 函数

go 程序可以在导入包时执行包初始化函数。这个函数名为 ​​init​​,格式如下:

func init() {
/*...*/
}

没有参数表,没有返回值。当一个包被导入时,此函数被会自动执行,而且只会执行一次。哪怕你的包在很多地方被导入,初始化也只进行一次。

2. 示例

接下来我们需要编写一个包,这个包用于计算一个 ​​byte​​ 类型的整数包含的 2 进制 1 的个数。

例1:数字 8 的 2 进制为 00001000,包含 1 个 1.
例2:数字 7 的 2 进制是 00000111,包含 3 个 1.

下面的程序在路径 ​​gopl/programstructure/package/bitcounte​​ 里。

2.1 思路

我们的解决方案非常暴力而且简单。byte 类型的数字一共只有 256 个,我们把每个数字里的 1 的个数数出来,保存到一个大小为 256 的数组里。

对于数字 n 来说,它的 2 进制 1 个数计算方式如下:


c(n)=c(n2)+n&1 c ( n ) = c ( n 2 ) + n & 1

2.2 程序代码

  • Count 函数
package bitcounter

import "fmt"

var pc [256]byte

// 执行包初始化
func init() {
fmt.Println("Hello, this is init function")
for i := range pc {
pc[i] = pc[i/2] + byte(i&1)
}
}

func Count(x byte) byte {
return
  • 示例程序
package bitcounter

import "fmt"

func ExampleOne() {
var x byte = 5
fmt.Printf("bitcount(%d) = %d\n", x, Count(x))
// output: bitcount(5) = 2
}

func ExampleTwo() {
var x byte = 255
fmt.Printf("bitcount(%d) = %d\n", x, Count(x))
// output: bitcount(255) = 8
  • 运行
$ cd bitcounter
$ go test -v


022-包初始化_包初始化


3. 总结

  • 掌握包初始化函数 init

练习:

  1. 上面的程序只能计算 byte 类型的整数。请你修改成可以计算 int64 类型的整数。
  2. 你还有其它算法来计算整数中 2 进制 1 的个数吗?