关于Golang包的小问答

golang包,有开发经验的应该是十分清楚了,这里仅仅以问答形式做些日常记录。

1 导入的包名称有冲突时如何处理?

例如math/rand包和crypto/rand包,那么导入声明必须至少为一个同名包指定一个新的包名以避免冲突。这叫做导入包的重命名。

import (
    "crypto/rand"
    mrand "math/rand" // alternative name mrand avoids conflict
)

2 匿名导入是什么?为什么?如何做?

匿名导入是指导入了某个第三方包,但是不需要显示使用它,这时就可以使用匿名导入。

可能会有人问,什么场景下会导入某个包而不使用呢?这是因为 Go 语言的代码文件中可以存在的init() 函数,它会在包文件第一次被导入的时候运行。

那么如何做,go语言本身在编译时是会对未使用导入包的代码进行报错的,所以匿名包导入代码形式如下:

import _ "image/png" // register PNG decoder

3 什么是内部包?有什么需求场景吗?

下面这段引用自《go语言圣经》中的一段,讲解的全面直观。

在Go语音程序中,包的封装机制是一个重要的特性。没有导出的标识符只在同一个包内部可以访问,而导出的标识符则是面向全宇宙都是可见的。

有时候,一个中间的状态可能也是有用的,对于一小部分信任的包是可见的,但并不是对所有调用者都可见。例如,当我们计划将一个大的包拆分为很多小的更容易维护的子包,但是我们并不想将内部的子包结构也完全暴露出去。同时,我们可能还希望在内部子包之间共享一些通用的处理包,或者我们只是想实验一个新包的还并不稳定的接口,暂时只暴露给一些受限制的用户使用。

为了满足这些需求,Go语言的构建工具对包含internal名字的路径段的包导入路径做了特殊处理。这种包叫internal包,一个internal包只能被和internal目录有同一个父目录的包所导入。例如,net/http/internal/chunked内部包只能被net/http/httputil或net/http包导入,但是不能被net/url包导入。不过net/url包却可以导入net/http/httputil包。

net/http
net/http/internal/chunked
net/http/httputil
net/url