挂代理是什么意思(Go)

 2025-08-10 05:54:01  阅读 516  评论 0

摘要:这是一篇基础文章,主要帮新手解决 GOPATH 和 Go Module 的问题。希望这篇文章能够为你彻底解惑。本文作者:Kade。本文的行文风格跟普通的文章不一样,是一种沉浸式的、笔记式的、或者视频稿的风格。不知道你是否会喜欢。注: 本文基于 go1.16, macOS 环境01 相关概念梳理注:

这是一篇基础文章,主要帮新手解决 GOPATH 和 Go Module 的问题。希望这篇文章能够为你彻底解惑。本文作者:Kade。

本文的行文风格跟普通的文章不一样,是一种沉浸式的、笔记式的、或者视频稿的风格。不知道你是否会喜欢。

注: 本文基于 go1.16, macOS 环境

01 相关概念梳理

注: 详细的可以完整阅读 Go 官方文档及 Wiki, 为了通俗一点, 文中某些描述可能不是很严谨!

首先需要清楚 Go 项目中包(package)和模块(module)的概念, 简单描述一下:

包(package)是用来管理 .go 文件的, 相关概念: 包目录, 包名, 包路径/包导入路径/导入路径它是源代码的集合, 由一个或多个源文件组成: 一个目录最多只能有一个包, 一个包只能存在于一个目录模块(module)是用来管理包的, 相关概念: 模块目录, 模块路径它是的集合, 由零个或多个组成: 一个目录最多只能有一个模块, 一个模块只能存在于一个目录 ; 一个模块目录里必须要有go.mod文件

02 代码组织的两种模式

注: 文中描述模式时使用小写(强迫症); 相关的发展历史可在社区了解

GOPATH mode(gopath模式): 通过配置 GO111MODULE=off 强制开启$GOPATH默认为用户家目录下的go目录, 即 ~/go$GOPATH可以设置多个目录, 可以实现依赖包存放在一个目录, 自己项目的包存放在另外一个目录包需要存放在$GOPATH/src下的子目录中, 包目录相对于$GOPATH/src的相对路径则为包的导入路径习惯上, 包所在的目录名与包名相同(不是必须)使用go get下载的包也是存放在$GOPATH/src目录中依赖包可以放在vendor目录中没有模块相关的概念module mode(gomod模式): 通过配置GO111MODULE=on强制开启$GOPATH默认为用户家目录下的go目录, 即 ~/go模块目录可以是任何目录, 包必须在某个模块中模块路径需要在模块目录下的 go.mod 文件中使用module指令指定习惯上, 模块下的包所在的目录名与包名相同(不是必须)使用go get下载的包存放在$GOPATH/pkg/mod下的相关目录中通过 go 命令的参数-mod=vendor可以支持 main 包下的vendor目录有模块相关的概念及配置, 比如: GOPROXY, GOPRIVATE, GOSUMDB等

注: GO111MODULE配置还有一个值是auto, 意思是具体 go 使用哪一种模式由 go 来判断并决定, 不同版本的判断不同, 效果不同, 所有建议使用 go 之前先明确设置GO111MODULE的值为 off 或者 on

注: gomod 模式中只保留了部分的 vendor 特性支持, 不建议日常开发中使用, 一般用作依赖存档或 CI/CD 使用

注: gopath 模式基本废弃, 不建议再使用, 如果有老项目仍在使用, 建议着手迁移到 gomod 模式, 如果迁移有问题, 可以在社区交流讨论, 或向官方求助

03 两种模式的使用示例

gopath 模式(官方已经准备废弃,不建议使用)

开启gopath模式, 设置GO111MODULE值为off
MacBooknbsp;#1.设置
MacBooknbsp;exportGO111MODULE=off
MacBooknbsp;#需要永久配置的话,需要修改相关的配置文件
MacBooknbsp;#比如:~/.bash_profile或~/.bashrc等
MacBooknbsp;#
MacBooknbsp;#建议使用下面的方法:
MacBooknbsp;goenv-wGO111MODULE=off

MacBooknbsp;#2.验证
MacBooknbsp;goenvGO111MODULE
off
MacBook$
根据需要设置GOPATH, 默认值为~/go, 建议使用默认(这里为了演示设置了其他目录)
MacBooknbsp;#1.设置
MacBooknbsp;exportGOPATH=/Users/kadefor/examples/gopath_mode
MacBooknbsp;#同上建议:
MacBooknbsp;goenv-wGOPATH=/Users/kadefor/examples/gopath_mode

MacBooknbsp;#2.验证
MacBooknbsp;goenvGOPATH
/Users/kadefor/examples/gopath_mode
MacBook$
日常开发(使用labstack/echo这个 web 开发框架为例)
MacBooknbsp;goenvGO111MODULE
off
MacBooknbsp;goenvGOPATH
/Users/kadefor/examples/gopath_mode

MacBooknbsp;pwd
/Users/kadefor/examples/gopath_mode/src

MacBooknbsp;tree.
.
└──github.com
└──myrepo
└──helloworld
└──main.go

3directories,1file
MacBooknbsp;cdgithub.com/myrepo/helloworld/
MacBook$
MacBooknbsp;#项目代码放在`GOPATH/src`下,一般是放在某个子目录里
MacBooknbsp;#相对于`GOPATH/src`的相对目录路径即为包导入路径
MacBooknbsp;#比如说,有一个包cc在src目录下的`aa/bb/cc`目录里
MacBooknbsp;#那它的导入路径就是"aa/bb/cc"
MacBook$
MacBooknbsp;#这里github.com/myrepo/helloworld目录下有个main包:
MacBooknbsp;pwd
/Users/kadefor/examples/gopath_mode/src/github.com/myrepo/helloworld
MacBooknbsp;ls
main.go

MacBooknbsp;head-8main.go
packagemain

import(
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
"net/http"
)

MacBooknbsp;#gopath模式下,go找包会在`GOROOT`,`GOPATH/src`,vendor目录下去找
MacBooknbsp;#比如这里导入的"github.com/labstack/echo"
MacBooknbsp;#运行看看:
MacBooknbsp;gorun.
main.go:4:2:cannotfindpackage"github.com/labstack/echo"inanyof:
/Users/kadefor/sdk/go/src/github.com/labstack/echo(from$GOROOT)
/Users/kadefor/examples/gopath_mode/src/github.com/labstack/echo(from$GOPATH)
main.go:5:2:cannotfindpackage"github.com/labstack/echo/middleware"inanyof:
/Users/kadefor/sdk/go/src/github.com/labstack/echo/middleware(from$GOROOT)
/Users/kadefor/examples/gopath_mode/src/github.com/labstack/echo/middleware(from$GOPATH)

MacBooknbsp;#现在就需要下载依赖的包
MacBooknbsp;#方法一般有:
MacBooknbsp;#1.gogetgithub.com/labstack/echo它还会同时下载相应的依赖包,简单
MacBooknbsp;#但是,某些包可能因为网络原因访问不了--!可以挂代理
MacBooknbsp;#2.想办法把包下载回来解压到`GOPATH/src`目录里,并保留包目录的结构
MacBooknbsp;#比如gitclone或者去github上点鼠标下载并解压到`GOPATH/src`目录里
MacBooknbsp;#3.使用第三方的包管理工具,比如dep,govendor等
MacBooknbsp;#第三方包管理工具一般是使用vendor特性,并支持维护包的版本
MacBooknbsp;#这样的工具在gopath模式里使用比较多,因为,goget的方法不支持包版本!

MacBooknbsp;#现在我挂代理使用goget
MacBooknbsp;exporthttps_proxy=http://127.0.0.1:7890http_proxy=http://127.0.0.1:7890all_proxy=socks5://127.0.0.1:7890

MacBooknbsp;tree`goenvGOPATH`/src-L3
/Users/kadefor/examples/gopath_mode/src
└──github.com
└──myrepo
└──helloworld

3directories,0files

MacBooknbsp;goget-v-u-dgithub.com/labstack/echo
github.com/labstack/echo(download)

MacBooknbsp;tree`goenvGOPATH`/src-L3
/Users/kadefor/examples/gopath_mode/src
├──github.com
│├──labstack
││├──echo
││└──gommon
│├──mattn
││├──go-colorable
││└──go-isatty
│├──myrepo
││└──helloworld
│└──valyala
│└──fasttemplate
└──golang.org
└──x
├──crypto
├──net
├──sys
└──text

17directories,0files

MacBooknbsp;#其他多出来的就是labstack/echo的依赖包
MacBooknbsp;#现在运行:
MacBooknbsp;gorun.
../../labstack/echo/middleware/jwt.go:9:2:cannotfindpackage"github.com/dgrijalva/jwt-go"inanyof:
/Users/kadefor/sdk/go/src/github.com/dgrijalva/jwt-go(from$GOROOT)
/Users/kadefor/examples/gopath_mode/src/github.com/dgrijalva/jwt-go(from$GOPATH)
../../labstack/echo/middleware/rate_limiter.go:9:2:cannotfindpackage"golang.org/x/time/rate"inanyof:
/Users/kadefor/sdk/go/src/golang.org/x/time/rate(from$GOROOT)
/Users/kadefor/examples/gopath_mode/src/golang.org/x/time/rate(from$GOPATH)

MacBooknbsp;#晕!还有一个包没下载!
MacBook$
MacBooknbsp;grep'echo/middleware'main.go
"github.com/labstack/echo/middleware"

MacBooknbsp;goget-v-dgithub.com/labstack/echo/middleware
github.com/dgrijalva/jwt-go(download)
get"golang.org/x/time/rate":foundmetatagvcs.metaImport{Prefix:"golang.org/x/time",VCS:"git",RepoRoot:"https://go.googlesource.com/time"}at//golang.org/x/time/rate?go-get=1
get"golang.org/x/time/rate":verifyingnon-authoritativemetatag
golang.org/x/time(download)

MacBooknbsp;#再来:
MacBooknbsp;gorun.
⇨httpserverstartedon[::]:1323
^Csignal:interrupt

MacBooknbsp;#项目已经运行起来了,下面再演示一下自己项目下的其他包的使用
MacBooknbsp;pwd
/Users/kadefor/examples/gopath_mode/src/github.com/myrepo/helloworld
MacBooknbsp;ls
main.go
MacBooknbsp;mkdirabc
MacBooknbsp;pwd
/Users/kadefor/examples/gopath_mode/src/github.com/myrepo/helloworld
MacBooknbsp;cdabc
MacBooknbsp;pwd
/Users/kadefor/examples/gopath_mode/src/github.com/myrepo/helloworld/abc
MacBooknbsp;#怎么用这个包呢?导入路径是什么?
MacBooknbsp;#相对于src的相对路径就是abc这个包的导入路径:
MacBooknbsp;#github.com/myrepo/helloworld/abc

MacBooknbsp;catabc.go
packageabc

import"fmt"

funcPrint(){
fmt.Println("GOPATHmode:Hello,ABC")
}
MacBooknbsp;cd..
MacBooknbsp;catmain.go
packagemain

import(
"github.com/myrepo/helloworld/abc"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
"net/http"
)

funcmain(){
abc.Print()

e:=echo.New()

e.Use(middleware.Logger())
e.Use(middleware.Recover())

e.GET("/",hello)

e.Logger.Fatal(e.Start(":1323"))
}

funchello(cecho.Context)error{
returnc.String(http.StatusOK,"Hello,World!")
}

MacBooknbsp;cd..
MacBooknbsp;gorunmain.go
GOPATHmode:Hello,ABC
⇨httpserverstartedon[::]:1323
^Csignal:interrupt
MacBooknbsp;#接下来演示一下vendor
MacBooknbsp;pwd
/Users/kadefor/examples/gopath_mode/src/github.com/myrepo/helloworld
MacBooknbsp;mkdirvendor
MacBooknbsp;mkdir-pvendor/github.com/myrepo/helloworld/
MacBooknbsp;cp-aabcvendor/github.com/myrepo/helloworld/
MacBooknbsp;#改一下vendor下abc那个包,看看效果
MacBooknbsp;vimvendor/github.com/myrepo/helloworld/abc/abc.go

MacBooknbsp;tree.
.
├──abc
│└──abc.go
├──main.go
└──vendor
└──github.com
└──myrepo
└──helloworld
└──abc
└──abc.go

6directories,3files

MacBooknbsp;catabc/abc.go
packageabc

import"fmt"

funcPrint(){
fmt.Println("GOPATHmode:Hello,ABC")
}

MacBooknbsp;catvendor/github.com/myrepo/helloworld/abc/abc.go
packageabc

import"fmt"

funcPrint(){
fmt.Println("GOPATHmodevendor:Hello,ABC")
}

MacBooknbsp;#运行后输出什么呢?
MacBooknbsp;gorun.
GOPATHmodevendor:Hello,ABC
⇨httpserverstartedon[::]:1323
^Csignal:interrupt

MacBooknbsp;#我们也可以把所有的依赖包都放到vendor目录下
MacBooknbsp;#这样的作用是:
MacBooknbsp;#1.可以把依赖存档,就算源仓库删除了,我们的项目同样可以运行
MacBooknbsp;#2.保存我们自己修改后的第三方包
MacBooknbsp;#
MacBooknbsp;#但是手动去做太麻烦了,所以在gopath模式中一般会使用第三方的包管理工具
MacBooknbsp;#使用主流的第三方包管理工具还有一个好处是:迁移到gomod模式比较简单!
MacBook$

gomod 模式(官方建议使用)

开启gomod模式, 设置GO111MODULE值为on
MacBooknbsp;#1.设置
MacBooknbsp;exportGO111MODULE=on
MacBooknbsp;#需要永久配置的话,需要修改相关的配置文件
MacBooknbsp;#比如:~/.bash_profile或~/.bashrc等
MacBooknbsp;#
MacBooknbsp;#建议使用下面的方法:
MacBooknbsp;goenv-wGO111MODULE=on
MacBook$
MacBooknbsp;#2.验证
MacBooknbsp;goenvGO111MODULE
on
MacBook$
根据需要设置GOPATH, 默认值为~/go, 建议使用默认(这里为了演示设置了其他目录)
MacBooknbsp;#1.设置
MacBooknbsp;exportGOPATH=/Users/kadefor/examples/gomod_mode
MacBooknbsp;#同上建议:
MacBooknbsp;goenv-wGOPATH=/Users/kadefor/examples/gomod_mode
MacBook$
MacBooknbsp;#2.验证
MacBooknbsp;goenvGOPATH
/Users/kadefor/examples/gomod_mode
MacBook$
设置GOPROXY
MacBooknbsp;#1.设置
MacBooknbsp;exportGOPROXY=https://goproxy.cn,direct
MacBooknbsp;#同上建议:
MacBooknbsp;goenv-wGOPROXY=https://goproxy.cn,direct
MacBook$
MacBooknbsp;#有官方的proxy,但是网络原因访问不了
MacBooknbsp;#使用proxy的好处:
MacBooknbsp;#1.一般公共的proxy都会上CDN,模块下载速度快
MacBooknbsp;#2.proxy相当于一个中心化的模块版本镜像,只要proxy上的缓存不删除
MacBooknbsp;#就算源仓库删除了,项目还是可以构建
MacBooknbsp;#
MacBooknbsp;#公司内部如果私有模块比较多,比较复杂,可以自建proxy
MacBooknbsp;#由自建的proxy去控制哪些模块是私有的,哪些是公有的
MacBooknbsp;#这样对于公司内部的开发来说是透明的,不需要再关注私有模块
MacBooknbsp;#
日常开发(使用labstack/echo这个 web 开发框架为例)
MacBooknbsp;pwd
/tmp/helloworld
MacBooknbsp;#使用gomod模式后,项目就可以随便放在某个目录了,但是,项目必须在某个模块内
MacBooknbsp;#如果是新建的项目,需要自己创建项目所在模块

MacBooknbsp;gomodinitgithub.com/myrepo/helloworld
go:creatingnewgo.mod:modulegithub.com/myrepo/helloworld
go:toaddmodulerequirementsandsums:
gomodtidy

MacBooknbsp;catgo.mod
modulegithub.com/myrepo/helloworld

go1.16

MacBooknbsp;#这里指定的模块路径为github.com/myrepo/helloworld
MacBooknbsp;#也可以指定其他的,比如abc,xxx/ooo等等
MacBooknbsp;#也有限制,有几个特殊的不行,哪些?自己找找:-)
MacBook$
MacBooknbsp;#这个模块路径一般和源码仓库的路径一致
MacBooknbsp;#这个模块路径会做为模块目录下包的导入路径的前缀
MacBooknbsp;#比如,如果当前模块下有个包abc,则这个包的导入路径为:
MacBooknbsp;#github.com/myrepo/helloworld/abc

MacBooknbsp;vimmain.go
MacBooknbsp;catmain.go
packagemain

import(
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"net/http"
)

funcmain(){
e:=echo.New()

e.Use(middleware.Logger())
e.Use(middleware.Recover())

e.GET("/",hello)

e.Logger.Fatal(e.Start(":1323"))
}

funchello(cecho.Context)error{
returnc.String(http.StatusOK,"Hello,World!")
}

MacBooknbsp;catgo.mod
modulegithub.com/myrepo/helloworld

go1.16

MacBooknbsp;#使用gomod模式的话,代码写好了,可以执行下面命令,自动下载依赖:
MacBooknbsp;#不需要手动一个一个去下载,直接执行:

MacBooknbsp;gomodtidy
go:findingmoduleforpackagegithub.com/labstack/echo/v4/middleware
go:findingmoduleforpackagegithub.com/labstack/echo/v4
go:downloadinggithub.com/labstack/echo/v4v4.2.0
go:foundgithub.com/labstack/echo/v4ingithub.com/labstack/echo/v4v4.2.0
go:foundgithub.com/labstack/echo/v4/middlewareingithub.com/labstack/echo/v4v4.2.0
go:downloadinggithub.com/labstack/gommonv0.3.0
go:downloadinggolang.org/x/cryptov0.0.0-20200820211705-5c72a883971a
go:downloadinggolang.org/x/netv0.0.0-20200822124328-c89045814202
go:downloadinggithub.com/stretchr/testifyv1.4.0
go:downloadinggithub.com/dgrijalva/jwt-gov3.2.0+incompatible
go:downloadinggolang.org/x/timev0.0.0-20201208040808-7e3f01d25324
go:downloadinggithub.com/mattn/go-colorablev0.1.7
go:downloadinggithub.com/mattn/go-isattyv0.0.12
go:downloadinggopkg.in/yaml.v2v2.2.2
go:downloadinggolang.org/x/sysv0.0.0-20200826173525-f9321e4c35a6
go:downloadinggolang.org/x/textv0.3.3

MacBooknbsp;#使用gomod模式的话,你用的依赖可能有不同的主版本号,如果是大于等于2,则在导入路径后面得加上/v2/v3/v4等
MacBook$
MacBooknbsp;#我想用labstack/echo的v4版本,则导入路径为:github.com/labstack/echo/v4
MacBooknbsp;#现在看看go.mod

MacBooknbsp;catgo.mod
modulegithub.com/myrepo/helloworld

go1.16

requiregithub.com/labstack/echo/v4v4.2.0

MacBooknbsp;#运行
MacBooknbsp;gorun.
v4.2.0
Highperformance,minimalistGowebframework
⇨httpserverstartedon[::]:1323
^Csignal:interrupt
MacBooknbsp;#使用gomod模式还是简单,只要你的依赖不奇葩:D
MacBook$
MacBooknbsp;#如果你使用支持自动补全的编辑器或者IDE,但它不会自动下载依赖(一般都会),如果模块没有提前下载,则自动补全无法正常使用
MacBooknbsp;#或者你需要使用模块特定的版本
MacBook\nbsp;#那就需要手动下载依赖了:

MacBooknbsp;goget-v-dgithub.com/labstack/echo/v3
goget:modulegithub.com/labstack/echo@upgradefound(v3.3.10+incompatible),butdoesnotcontainpackagegithub.com/labstack/echo/v3
MacBooknbsp;#这里需要特别说明一下,在gomod模式出现之前,有些模块已经有v2,v3等版本号了,但不是模块,所有就会有类似上面的错误

MacBooknbsp;#既然不是模块就不存在/v2,/v3这样的尾巴了
MacBooknbsp;goget-v-dgithub.com/labstack/echo@v3.3.10
goget:addedgithub.com/labstack/echov3.3.10+incompatible

MacBooknbsp;vimmain.go#改一下包导入路径
MacBooknbsp;catmain.go
packagemain

import(
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
"net/http"
)

funcmain(){
e:=echo.New()

e.Use(middleware.Logger())
e.Use(middleware.Recover())

e.GET("/",hello)

e.Logger.Fatal(e.Start(":1323"))
}

funchello(cecho.Context)error{
returnc.String(http.StatusOK,"Hello,World!")
}

MacBook\nbsp;catgo.mod
modulegithub.com/myrepo/helloworld

go1.16

require(
github.com/labstack/echov3.3.10+incompatible//indirect
github.com/labstack/echo/v4v4.2.0
)

MacBooknbsp;gomodtidy
MacBooknbsp;#变化
MacBook\nbsp;catgo.mod
modulegithub.com/myrepo/helloworld

go1.16

require(
github.com/dgrijalva/jwt-gov3.2.0+incompatible//indirect
github.com/labstack/echov3.3.10+incompatible
github.com/labstack/gommonv0.3.0//indirect
github.com/mattn/go-colorablev0.1.7//indirect
github.com/valyala/fasttemplatev1.2.1//indirect
golang.org/x/cryptov0.0.0-20200820211705-5c72a883971a//indirect
golang.org/x/netv0.0.0-20200822124328-c89045814202//indirect
golang.org/x/sysv0.0.0-20200826173525-f9321e4c35a6//indirect
golang.org/x/textv0.3.3//indirect
)

MacBook\nbsp;gorun.
v3.3.10-dev
Highperformance,minimalistGowebframework
⇨httpserverstartedon[::]:1323
^Csignal:interrupt

04 总结

gomod 模式相对于 gopath 模式来说还是比较新, 所以 gomod 模式下还有很多操作在本文中就没有写了, 如果有人喜欢这种沉浸式的、笔记式的、或者视频稿的风格, 那后面就再写写 gopath 模式迁移到 gomod 模式的操作, 以及 gomod 模式下模块的常见管理操作, 如果不喜欢这种风格, 那就算了 :D

Go 项目中代码组织的两种模式

版权声明:我们致力于保护作者版权,注重分享,被刊用文章【挂代理是什么意思(Go)】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!;

原文链接:https://www.yxiso.com/zhishi/2048542.html

发表评论:

关于我们
院校搜的目标不仅是为用户提供数据和信息,更是成为每一位学子梦想实现的桥梁。我们相信,通过准确的信息与专业的指导,每一位学子都能找到属于自己的教育之路,迈向成功的未来。助力每一个梦想,实现更美好的未来!
联系方式
电话:
地址:广东省中山市
Email:beimuxi@protonmail.com

Copyright © 2022 院校搜 Inc. 保留所有权利。 Powered by BEIMUCMS 3.0.3

页面耗时0.1036秒, 内存占用1.94 MB, 访问数据库24次

陕ICP备14005772号-15