# [译] part 7: golang 包

https://juejin.im/post/5cbdf9076fb9a0321141ae0b

## main 函数和 main 包

geometry.go 的代码如下，

//geometry.gopackage main import "fmt"func main() {      fmt.Println("Geometrical shape properties")}

src      geometry            gemometry.gobin      geometry

## 创建自定义包

//rectprops.gopackage rectangleimport "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.gopackage 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.gopackage rectangleimport "math"  import "fmt"/* * init function added */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.gopackage 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. rectLenrectWidth变量从 main 函数级别移动到包级别。
2. 添加了一个 init 函数。如果rectLenrectWidth小于零则使用log.Fatal函数打印日志并终止。

main 包的初始化顺序是

1. 首先初始化导入的包。因此 rectangle 包首先被初始化
2. 接下来初始化包级别变量rectLenrectWidth
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.gopackage main import (        "geometry/rectangle" //importing custom package)func main() {}

package mainimport (      "geometry/rectangle" )var _ = rectangle.Area //error silencerfunc main() {}

package main import (        _ "geometry/rectangle" )func main() {}