VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > 简明python教程 >
  • 25. Go 语言中关于包导入必学的 8 个知识点

1. 单行导入与多行导入

在 Go 语言中,一个包可包含多个 .go 文件(这些文件必须得在同一级文件夹中),只要这些 .go 文件的头部都使用 package 关键字声明了同一个包。

导入包主要可分为两种方式:

  • 单行导入

import "fmt"
import "sync" 
  • 多行导入

import(
    "fmt"
    "sync"
)

如你所见,Go 语言中 导入的包,必须得用双引号包含,在这里吐槽一下。

2. 使用别名

在一些场景下,我们可能需要对导入的包进行重新命名,比如

  • 我们导入了两个具有同一包名的包时产生冲突,此时这里为其中一个包定义别名

import (
    "crypto/rand"
    mrand "math/rand" // 将名称替换为mrand避免冲突
)
  • 我们导入了一个名字很长的包,为了避免后面都写这么长串的包名,可以这样定义别名

import hw "helloworldtestmodule"
  • 防止导入的包名和本地的变量发生冲突,比如 path 这个很常用的变量名和导入的标准包冲突。

import pathpkg "path"

3. 使用点操作

如里在我们程序内部里频繁使用了一个工具包,比如 fmt,那每次使用它的打印函数打印时,都要 包名+方法名。

对于这种使用高频的包,可以在导入的时,就把它定义会 "自己人"(方法是使用一个 . ),自己人的话,不分彼此,它的方法,就是我们的方法。

从此,我们打印再也不用加 fmt 了。

import . "fmt"

func main() {
    Println("hello, world")
}

但这种用法,会有一定的隐患,就是导入的包里可能有函数,会和我们自己的函数发生冲突。

4. 包的初始化

每个包都允许有一个或多个的 init 函数,当这个包被导入时,会执行该包的这个 init 函数,做一些初始化任务。

对于 init 函数的执行有两点需要注意

  1. init 函数优先于 main 函数执行

  2. 在一个包引用链中,包的初始化是深度优先的。比如,有这样一个包引用关系:main→A→B→C,那么初始化顺序为

    C.initB.initA.initmain
    

5. 包的匿名导入

当我们导入一个包时,如果这个包没有被使用到,在编译时,是会报错的。

但是有些情况下,我们导入一个包,只想执行包里的 init 函数,来运行一些初始化任务,此时怎么办呢?

可以使用匿名导入,用法如下,其中下划线为空白标识符,并不能被访问

// 注册一个PNG decoder
import _ "image/png"

由于导入时,会执行 init 函数,所以编译时,仍然会将这个包编译到可执行文件中。

6. 导入的是路径还是包?

当我们使用 import 导入 testmodule/foo 时,初学者,经常会问,这个 foo 到底是一个包呢,还是只是包所在目录名?

import "testmodule/foo"

为了得出这个结论,专门做了个试验(请看「第七点里的代码示例」),最后得出的结论是:

  • 导入时,是按照目录导入。导入目录后,可以使用这个目录下的所有包。

  • 出于习惯,包名和目录名通常会设置成一样,所以会让你有一种你导入的是包的错觉。

7. 相对导入和绝对导入

据我了解在 Go 1.10 之前,好像是不支持相对导入的,在 Go 1.10 之后才可以。

绝对导入:从 $GOPATH/src 或 $GOROOT 或者 $GOPATH/pkg/mod 目录下搜索包并导入

相对导入:从当前目录中搜索包并开始导入。就像下面这样

import (
    "./module1"
    "../module2"
    "../../module3"
    "../module4/module5"
)

分别举个例子吧

一、使用绝对导入

有如下这样的目录结构(注意确保当前目录在 GOPATH 下)

其中 main.go 是这样的

package main

import (
    "app/utilset"   // 这种使用的就是绝对路径导入
)

func main() {
    utils.PrintHello()
}

而在 main.go 的同级目录下,还有另外一个文件夹 utilset ,为了让你理解 「第六点:import 导入的是路径而不是包」,我在 utilset 目录下定义了一个 hello.go 文件,这个go文件定义所属包为 utils

package utils

import "fmt"

func PrintHello(){
    fmt.Println("Hello, 我在 utilset 目录下的 utils 包里")
}

运行结果如下

二、使用相对导入

还是上面的代码,将绝对导入改为相对导入后

将 GOPATH 路径设置回去(请对比上面使用绝对路径的 GOPATH)


相关教程