go的入门概念理解与拙见(1) | 青训营笔记

284 阅读6分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第4篇笔记

在大作业开发中实际遇到的问题(从0开始)

工具的选择

在入门一门语言时,除了配置环境之外,另外一个很重要的就是给自己选择一个合适的工具,好的工具能让效率大大提示。

而我们通常会有两个选择,vscode 和 jet brains全家桶。而vscode因为其独特的轻巧,加上数量庞大且功能强大的插件,往往会成为很多人的选择。但是我因为使用全家桶系列的比较多。于是在权衡之下,选择了goland作为我go语言的开发工具。

go作为一个相对朝气蓬勃的语言,其适配环境,以及集成环境上的使用方面,教程往往比较欠缺,有些时候,我们会遇到一些问题,有些问题可以轻松的解决,而有些问题则会耗费我们较长的时间。接下来我会把我在青训营中,学习,包括大作业开发时候遇到的一些经典的问题罗列出来,并给定一个相对可以解决的办法。

GOROOT,GOPATH,GOMOD,GOPROXY傻傻分不清

这些概念在我刚开始接触go的时候对我那个并不太灵光的小脑袋,产生了不小的冲击,

于是逛遍了博客,找到相对满意的答案。

前倾提要,在成功安装好go语言的环境,并且配置好相关的环境变量后,我们可以通过控制台来查看go的环境信息

$ go env

GOPATH

GOPATH 是 Go语言中使用的一个环境变量,它使用绝对路径提供项目的工作目录

  • 工作目录:一个工程开发的相对参考目录。工作区的概念与工作目录的概念也是类似的。如果不使用工作目录的概念,在多人开发时,每个人有一套自己的目录结构,读取配置文件的位置不统一,输出的二进制运行文件也不统一,这样会导致开发的标准不统一,影响开发效率

  • 使用GOPATH的工程结构:

    1. 在 GOPATH 指定的工作目录下,代码总是会保存在 GOPATH/src目录下。在工程经过gobuildgoinstallgoget等指令后,会将产生的二进制可执行文件放在GOPATH/src 目录下。在工程经过 go build、go install 或 go get 等指令后,会将产生的二进制可执行文件放在 GOPATH/bin目录下,生成的中间缓存文件会被保存在 $GOPATH/pkg 下。
    2. 如果需要将整个源码添加到版本管理工具(Version Control System,VCS)中时,只需要添加 $GOPATH/src 目录的源码即可。bin 和 pkg 目录的内容都可以由 src 目录生成。
    3. 其中,Global GOPATH 代表全局 GOPATH,一般来源于系统环境变量中的 GOPATH;Project GOPATH 代表项目所使用的 GOPATH,该设置会被保存在工作目录的 .idea 目录下,不会被设置到环境变量的 GOPATH 中,但会在编译时使用到这个目录。建议在开发时只填写项目 GOPATH,每一个项目尽量只设置一个 GOPATH,不使用多个 GOPATH 和全局的 GOPATH。
  • GOPATH的缺点:

    当我们的第三方包不是官方库时都要放在GOPATH/src下才可以使用

    我们通常使用go get指令来获取第三方的包

    (在goland中在我们配置好goproxy之后ide会帮助我们自动获取依赖,但是配置过程问题会有一个问题,我们会在后面具体介绍)

    go get 最长用在当我们想用别人公开在github上的包,可以帮我们从网上clone到GOPATH/src下。 是不是听起来很方便?会让src下的项目变得很复杂,除了有自己的项目还有其他第三方库的项目。 在如果,我们的不同的项目采用的第三方库是不同的版本怎么办,go1.11以前是要设顶多组不同的GOPATH,虽然go社区也有开发相对应的包管理工具,如Vender,Dep来结局该问题,但它们都不是官方的。

GOROOT

GOROOT就是go语言的安装路径,此时安装在**/usr/local/go**下可以看到src, bin, pkg三个文件夹,标准的Go语言代码库中包含了大量的包,并且在安装 Go 的时候多数会自动安装到系统中。我们可以在 $GOROOT/src/pkg 目录中查看这些包。当我们 import内置包的时候,并不需要额外安装,当程序运行时,会先去GOROOT下找相应的包来运行。

  • 注:
    1. 当执行golang程序,需要获取import的包时,编译器回先去GOROOT路径下的src文件夹找有没有我们在程序中import的包
    2. 如果在GOROOT下没有找到,就会去GOPATH下src下找这个包,所以只要GOROOT跟GOPATH下都没找到包的话就会报错

GOMOD

Go Modules很像java的maven,将第三方的库放在本地的空间,但它不是自动的下载包的,我们可以使用命令开启和关闭go mod

go env -w GO111MODULE=on //打开

go env -w GO111MODULE=off //关闭
  • GO111MODULE有三个不同的值

  • auto

当存在 go.mod 文件时或处于 GOPATH 外, 其行为均会等同于于 GO111MODULE=on。这意味着在 Go 1.13 及之后的版本你可以将所有的代码仓库均存储在 GOPATH 下。 当处于 GOPATH 内且没有 go.mod 文件存在时其行为会等同于 GO111MODULE=off。

  • on 即使项目在您的 GOPATH 中,GO111MODULE = on 仍将强制使用 Go 模块。需要 go.mod 正常工作

  • off 强制 Go 表现出 GOPATH 方式,即使在 GOPATH 之外。

下载下来的第三方库在哪呢?其实就在GOPATH/pkg/mod文件夹里面

若要使用gomod进行包管理,需要在项目根目录下执行

go mod init

之后就可以使用go get ***、import等操作.

gomod 的使用配置

设置环境变量

go env -w GO111MODULE=on go env -w GOPROXY= “国内比较出名的都可以”

go get使用

使用go module之后,go get 拉取依赖的方式就发生了变化 但是由于goland的存在,导致我们在配置好goproxy之后并不需要去手动的获取依赖,goland会自动的帮我们获取依赖。

gomod的相关操作
//初始化一个moudle,模块名为你项目名
go mod init 模块名
//下载modules到本地cache,目前所有模块版本数据均缓存在 $GOPATH/pkg/mod和 $GOPATH/pkg/sum 下
go mod download
//更新到最新版本

go get github.com/gogf/gf@version
//增加缺失的包,移除没用的包

go mod tidy

做个总结,这几个概念在刚刚入门时候的冲击力还是比较大的,不过从上面我们从其概念上可以发现,其实并没有那么可怕,可以理解为,语言环境所保存的位置,项目编译产出的文件的保存位置,直接从远程仓库处理依赖的小东西,以及帮助我们突破不可名状的限制来快速获取到依赖的通道。 不要害怕,勇敢的向前冲,世间万物总是会有着其自我的解决之道的

在实践中遇到的实际问题

1.如何具体正确的配置goproxy

现在使用的比较多的那两个都可以

我觉的这两个用哪个都ok,但是相对来说后者在使用文档上要更加详细。

可能会更少的降低重复配置的风险,同时提供了图文,包括如何在goland上面配置的具体位置。

不过这里我想讲的是,有时候配置的proxy可能只在一次起作用,所以无论在用这两个的哪一个,请一定不要网易配置好环境变量。

  1. 为什么我已经配置好了goproxy我上面导进来的包还是红的。

    • 这里其实是一个其实蛮容易解决的问题,但是当时也给我绕了不少弯路

    • 很多时候并不是所有的包都导入不进来,一般来说这种情况出现在配置之前,在配置之后有偶尔几个迟迟无法导入一般有这样的几个原因。

    (1). 第一个就是goproxy没有被配置成功,我们可以按照 go env -----> 环境变量 --->goland这样的一个顺序来进行检查。一般若是因为proxy的问题,都会在重新配置之后得到解决

    (2) 其次就是权限问题,因为我们可能会自然的把go的root放到c盘里面,这样子就会涉及到写入权限的问题,之所以我们平时没有感受到,是因为我们平时所用的账户权限都比较高,但是goland没有,所以一般在导入过程中会飘红,显示没有写入某个文件夹的权利。

    这里不要被网上的各种解除文件夹或者磁盘权限所误导,直接右键用管理员权限启动就完美解决了。如果你是用的toolbox来管理全家桶的化,在toolbox中有个选项,可以直接设置某个软件的权限,就剩下了手动设置的后顾之忧了。

ps.如果刚下下来goland打开控制台没有的话,去windows搜索栏搜一下cmd,或者powershell的路径cv到goland设置里面的一个terminal选项即可。

结束语

概念这个东西有时候很玄学,这里对于概念的理解整理,包括问题的提出以及解决是我在=初次上手时候比较令我头痛的部分,希望能够帮助到有需要的人。