golang 包的管理

以前看golang包管理时,感觉有点混乱,套用python,lua包管理的方式不行,直到今天(2018.10.19)才基本搞清楚golang包管理的意思。

使用包package目的

使用包的目的是为了更加方便的管理源码。golang的理念是用文件夹来管理(或者叫约束)同种类型或同种功能的源码,例如数学计算的源码都放入math文件夹下,系统相关的放入os文件夹下。

一个文件夹下的源码中所有包名必须一样,但是包名可以与文件名不一样。例如项目中涉及到数学计算,建立一个文件夹为math,为了让功能独立,我们每一个功能使用一个go文件,诸如add.go,sub.go,div.go等。一个go文件必须要在开头指定所在的包,语法为package xxx,我们可以写为package "mymath"。

如何使用包管理

如何使用上面的math模块呢? 如果是在同一个文件夹中(肯定也是在同一个package中),直接调用相关函数或全局变量,而不用加包名限制,加了反而出错。 如果不是同一个文件夹(注意不在同一个文件下,不能用一个包名),则首先要import该文件夹,然后使用包名限制来使用函数或者全局变量,例如mymath.Add()。

即,使用时import math,引用时却是mymath,并不是直接导入了math这个包,这一点很容易搞错。其中的原因是,import本质是解析math文件夹下的源码(当然math文件夹必须放在GOROOT或GOPATH目录的src文件夹下),然后导入了源码中的包mymath。

还有一个问题是,import math文件夹不会包含math文件夹下的子文件夹的源文件,也就是说如果想要包含文件夹下子文件,则要import指定到子文件夹名。同时子文件夹中源码的package包名也必须不一样。引用子文件夹中的源码时不必带上父文件夹中的包名,直接用包名即可。

import的本质:

import实际上是按顺序解析文件夹中所有的源文件。当一个源文件还导入了其它的包,那么先将其他的包导入进来。那么有三个问题要弄清楚:

  • 同一个文件多次引入的问题。例如,math文件夹下有a,b,c三个文件,a,b,c又同时import了另外一个文件夹other。那么当import math时,会多次引入other文件夹下的文件吗?答案是不会,一个文件只会被引入一次。
  • 循环引用的问题。例如math文件夹下的a文件源码引用了other文件夹,other文件夹中的文件又引用math。这种情况下该如何处理,循环递归直至crash吗?幸好,import机制不允许循环引用。所以不必担心这个问题。
  • 解析源文件时做了什么? 常量和变量进行初始化,最后执行init函数,如果存在的话(init函数不能主动被调用,无论是调用自己包中还是其他包中的)。 用一个图表示上面的过程:

 

import修饰操作

  • 点(.)操作

点(.)操作的含义是:点(.)标识的包导入后,调用该包中函数时可以省略前缀包名。点(.)操作的语法为:


import (
    . "package1"
    . "package2"
    . "package3"
    ...
)

下面的示例中,fmt包将使用点操作省略前缀包名,os包用法保持不变:

package main

import (
    . "fmt"
    "os"
)

func main() {
    for _, value := range os.Args {
        Println(value)
    }
}
  • 别名操作

别名操作的含义是:将导入的包命名为另一个容易记忆的别名。别名操作的语法为:

import p1 "package1"
import p2 "package2"
import p3 "package3"
...
import (
    p1 "package1"
    p2 "package2"
    p3 "package3"
    ...
)

下面的示例中,fmt包将使用别名操作重新命名为f,os包用法保持不变:

package main

import (
    f "fmt"
    "os"
)

func main() {
    for _, value := range os.Args {
        f.Println(value)
    }
}
  • 下划线(_)操作

下划线()操作的含义是:导入该包,但不导入整个包,而是执行该包中的init函数,因此无法通过包名来调用包中的其他函数。使用下划线()操作往往是为了注册包里的引擎,让外部可以方便地使用。下划线(_)操作的语法为:

import _ "package1"
import _ "package2"
import _ "package3"
...
import (
    _ "package1"
    _ "package2"
    _ "package3"
    ...
)

参考:

https://studygolang.com/articles/5831

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值