Go 内部包

2019/12/18 Go

在 Go 语言中,所有成员在包内均可访问,无论是否在同一源码文件中。但只有名称首字母为大写的成员可导出,在包外可视。

但是在进行代码重构时,我们会将一些内部模块陆续分离开来,以独立包的形式维护。这时,基于首字母大小写的访问权限控制则显示过于粗犷。我们希望这些包的可导出成员仅在特定范围内可访问,而不是向所有用户公开。

内部包机制提供了这种访问权限控制:所有保存在 internal 目录下的包都只能被其父目录下的包(含所有层次的子目录)访问

以下是内部包的结构示例:

src/
    internalTest/
        external/
            external.go
        internal/
            internal.go 
        test.go

各包文件代码如下:

// internalTest/external/external.go
package external

import "fmt"

func ExternalHello() {
    fmt.Println("ExternalHello")
}
// internalTest/internal/internal.go
package internal

import "fmt"

func InternalHello() {
    fmt.Println("InternalHello")
}
// internalTest/test.go
package internalTest

import (
    "internalTest/external"
    "internalTest/internal"
)

func Hello() {
    external.ExternalHello()
    internal.InternalHello()
}

测试文件:

// main.go
package main

import (
    "internalTest"
    "internalTest/external"
    //"internalTest/internal" // error: use of internal package internalTest/internal not allowed
)

func main() {
    internalTest.Hello()
    external.ExternalHello()
    //internal.InternalHello()
}

运行 main.go,输出如下:

ExternalHello
InternalHello
ExternalHello

如果将 main.go 中的已注释的代码去除注释,运行时会报错:

use of internal package internalTest/internal not allowed

internal 包和 external 包在同一级目录中,external 包首字母为大写的成员在 internalTest/test.go 以及 main.go 中均可以导出;而 internal 包首字母为大写的成员在 internalTest/test.go 中可导出,而在 main.go 中不可导出。

这样 internal 包就可以提供更为精确的访问权限控制。

Search

    Table of Contents