# [译] part 7: golang 包

834

## main 函数和 main 包

geometry.go 的代码如下，

``````//geometry.go
package main

import "fmt"

func main() {
fmt.Println("Geometrical shape properties")
}
``````

``````src
geometry
gemometry.go
bin
geometry
``````

## 创建自定义包

``````//rectprops.go
package rectangle

import "math"

func Area(len, wid float64) float64 {
area := len * wid
return area
}

func Diagonal(len, wid float64) float64 {
diagonal := math.Sqrt((len * len) + (wid * wid))
return diagonal
}
``````

## 导入自定义包

``````src
geometry
geometry.go
rectangle
rectprops.go
``````

`import "geometry/rectangle"` 是导入 rectangle 包的方式。

``````//geometry.go
package main

import (
"fmt"
"geometry/rectangle" //importing custom package
)

func main() {
var rectLen, rectWidth float64 = 6, 7
fmt.Println("Geometrical shape properties")
/*Area function of rectangle package used
*/
fmt.Printf("area of rectangle %.2f\n", rectangle.Area(rectLen, rectWidth))
/*Diagonal function of rectangle package used
*/
fmt.Printf("diagonal of the rectangle %.2f ",rectangle.Diagonal(rectLen, rectWidth))
}
``````

``````Geometrical shape properties
area of rectangle 42.00
diagonal of the rectangle 9.22
``````

## init 函数

``````func init() {
}
``````

init 函数用于执行初始化任务，也可用于在执行开始之前验证程序的正确性。

1. 首先初始化包级别变量
2. 接下来调用 init 函数。一个包可以有多个 init 函数（在单个文件中或分布在多个文件中），并按照它们呈现给编译器的顺序调用它们。

``````//rectprops.go
package rectangle

import "math"
import "fmt"

/*
*/
func init() {
fmt.Println("rectangle package initialized")
}
func Area(len, wid float64) float64 {
area := len * wid
return area
}

func Diagonal(len, wid float64) float64 {
diagonal := math.Sqrt((len * len) + (wid * wid))
return diagonal
}
``````

``````//geometry.go
package main

import (
"fmt"
"geometry/rectangle" //importing custom package
"log"
)
/*
* 1. package variables
*/
var rectLen, rectWidth float64 = 6, 7

/*
*2. init function to check if length and width are greater than zero
*/
func init() {
println("main package initialized")
if rectLen < 0 {
log.Fatal("length is less than zero")
}
if rectWidth < 0 {
log.Fatal("width is less than zero")
}
}

func main() {
fmt.Println("Geometrical shape properties")
fmt.Printf("area of rectangle %.2f\n", rectangle.Area(rectLen, rectWidth))
fmt.Printf("diagonal of the rectangle %.2f ",rectangle.Diagonal(rectLen, rectWidth))
}
``````

1. `rectLen``rectWidth`变量从 main 函数级别移动到包级别。
2. 添加了一个 init 函数。如果`rectLen``rectWidth`小于零则使用`log.Fatal`函数打印日志并终止。

main 包的初始化顺序是

1. 首先初始化导入的包。因此 rectangle 包首先被初始化
2. 接下来初始化包级别变量`rectLen``rectWidth`
3. 调用 init 函数
4. 最后调用 main 函数

``````rectangle package initialized
main package initialized
Geometrical shape properties
area of rectangle 42.00
diagonal of the rectangle 9.22
``````

``````rectangle package initialized
main package initialized
2017/04/04 00:28:20 length is less than zero
``````

## 使用`_`符号

Go 中导入包并且不在代码中的任何位置使用它是非法的。如果你这样做，编译器会报错。这样做的原因是为了避免大量未使用的包显著增加编译时间。用以下代码替换 geometry.go 中的代码，

``````//geometry.go
package main

import (

"geometry/rectangle" //importing custom package

)
func main() {

}
``````

``````package main

import (
"geometry/rectangle"
)

var _ = rectangle.Area //error silencer

func main() {

}
``````

``````package main

import (

_ "geometry/rectangle"

)
func main() {

}
``````