舍近求远,为什么 Golang 要这样读取本地的 package?

简介: 舍近求远,为什么 Golang 要这样读取本地的 package?

我们知道,Python 的第三方库一般是托管到 Pypi 上面的,使用 pip 命令进行安装。而 Golang 很多第三方库是托管在 Github 上面的,使用 go get 进行安装。


有时候,我们会发现一个很奇怪的现象,很多 Golang 的项目,在引用自己项目里面的包的时候,竟然用的是 Github 上面的地址。


例如我们看这个项目:https://github.com/kingname/handsome ,它的入口文件是main.go。我们打开这个文件,会看到里面import语句中,从 Github导入自身的util包:


640.png


可问题是,这个 util文件夹就在main.go旁边啊:


640 (1).png


如果是在 Python 里面,入口文件main.py旁边有一个util文件夹,这个文件夹里面有一个util.py的文件,那么我们直接写from util.util import xxx就可以导入util.py文件中的函数了。为什么 Golang 里面要从 Github 导入?那如果我更新了util/util.go文件里面的内容,但是我没有把这次修改上传到 Github 中,当我运行go run main.go的时候,运行的是老代码还是新代码?用的是我本地的版本还是 Github 上面的版本?


这个问题的关键,就在go.mod这个文件中。打开请看这个文件的第一行:


640 (2).png


可以看到,这个项目是使用 go mod 进行管理的,并且指定这个模块的名字,就叫做github.com/kingname/handsome


所以,当我们执行命令go run main.go的时候,Golang 的编译器知道自己就是github.com/kingname/handsome,那么main.go里面导入

github.com/kingname/handsome/util,实际上就是本项目自身根目录的 util文件夹中的包,它不会发起网络请求,不会从 Github 上面重新下载。每次运行的时候,使用的总是项目util/util.go中的内容。


但是,如果你现在在另外一个项目里面导入github.com/kingname/handsome/util,Golang 从go.mod中知道当前运行的项目跟即将导入的这个包不在同一个项目中,于是它就会去 Github 上面拉代码下来运行。


这个规则,可以在 Golang 的官方文档Module paths这一节找到:Go Modules Reference - The Go Programming Language[1]


参考文献


[1] Go Modules Reference - The Go Programming Language: https://go.dev/ref/mod#introduction


请关注微信公众号【未闻Code】获取更多精彩文章。


目录
相关文章
|
存储 Go
Golang语言基于go module方式管理包(package)
这篇文章详细介绍了Golang语言中基于go module方式管理包(package)的方法,包括Go Modules的发展历史、go module的介绍、常用命令和操作步骤,并通过代码示例展示了如何初始化项目、引入第三方包、组织代码结构以及运行测试。
388 3
|
Go
Golang语言基于GOPATH方式管理包(package)
这篇文章详细介绍了Golang语言中基于GOPATH方式管理包(package)的方法,包括包的概述、定义、引入格式、别名使用、匿名引入,以及如何快速入门自定义包,并通过具体代码案例展示了包的环境准备、代码编写、细节说明和程序运行。
128 3
|
Go
【golang】解决:missing go.sum entry for module providing package
【golang】解决:missing go.sum entry for module providing package
2260 0
|
设计模式 Go Python
层次分明井然有条,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang包管理机制(package)EP10
Go lang使用包(package)这种概念元素来统筹代码,所有代码功能上的可调用性都定义在包这个级别,如果我们需要调用依赖,那就“导包”就行了,无论是内部的还是外部的,使用import关键字即可。但事情往往没有那么简单,Go lang在包管理机制上走了不少弯路,虽然1.18版本的包管理已经趋于成熟,但前事不忘后事之师,我们还是需要了解一下这段历史。
层次分明井然有条,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang包管理机制(package)EP10
|
Linux Shell Go
gocommand:一个跨平台的golang命令行执行package
    最近在做一个项目的时候,需要使用golang来调用操作系统中的命令行,来执行shell命令或者直接调用第三方程序,这其中自然就用到了golang自带的exec.Command.     但是如果直接使用原生exec.
3111 0
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
455 4
Golang语言之管道channel快速入门篇
|
Go
Golang语言文件操作快速入门篇
这篇文章是关于Go语言文件操作快速入门的教程,涵盖了文件的读取、写入、复制操作以及使用标准库中的ioutil、bufio、os等包进行文件操作的详细案例。
177 4
Golang语言文件操作快速入门篇
|
Go
Golang语言之gRPC程序设计示例
这篇文章是关于Golang语言使用gRPC进行程序设计的详细教程,涵盖了RPC协议的介绍、gRPC环境的搭建、Protocol Buffers的使用、gRPC服务的编写和通信示例。
417 3
Golang语言之gRPC程序设计示例
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
244 4
|
Go 调度
Golang语言goroutine协程篇
这篇文章是关于Go语言goroutine协程的详细教程,涵盖了并发编程的常见术语、goroutine的创建和调度、使用sync.WaitGroup控制协程退出以及如何通过GOMAXPROCS设置程序并发时占用的CPU逻辑核心数。
533 4
Golang语言goroutine协程篇