## GOPATH 和 GOROOT
不同于其他语言,**go中没有项目的说法,只有包**, 其中有两个重要的路径,**`GOROOT`** 和 **`GOPATH`**
Go开发相关的环境变量如下:
* GOROOT:GOROOT就是Go的安装目录,(类似于java的JDK)
* GOPATH:GOPATH是我们的工作空间,保存go项目代码和第三方依赖包
**`GOPATH`**可以设置多个,其中,第一个将会是默认的包目录,使用 go get 下载的包都会在第一个path中的src目录下,使用 go install时,在哪个**`GOPATH`**中找到了这个包,就会在哪个`GOPATH`下的bin目录生成可执行文件
## 修改 GOPATH 和 GOROOT
* GOROOT
GOROOT是Go的安装路径。GOROOT在绝大多数情况下都不需要修改
【如下图所示则我的GORROT为:**D:\\development\\go**】,以下是GOROOT目录的内容:

可以看到GOROOT下有bin,doc和src目录。bin目录下有我们熟悉的go和gofmt工具。可以认为GOOROOT和Java里的JDK目录类似。
* GOPATH
GOPATH是开发时的工作目录。用于:
1. 保存编译后的二进制文件。
2. `go get`和`go install`命令会下载go代码到GOPATH。
3. import包时的搜索路径
使用GOPATH时,GO会在以下目录中搜索包:
1. `GOROOT/src`:该目录保存了Go标准库代码。
2. `GOPATH/src`:该目录保存了应用自身的代码和第三方依赖的代码。
假设程序中引入了如下的包:
~~~Go
import "Go-Player/src/chapter17/models"
~~~
第一步:Go会先去**GOROOT的scr目录**中查找,很显然它不是标准库的包,没找到。
第二步:继续在**GOPATH的src目录**去找,准确说是**`GOPATH/src/`Go-Player/src/chapter17/models**这个目录。如果该目录不存在,会报错找不到package。在使用GOPATH管理项目时,需要按照GO寻找package的规范来合理地保存和组织Go代码。
### 3、HelloWord——GOPATH版
(1)设置并查看GOPATH和GOROOT环境变量
* 安装go SKD目录:D:\\development\\go
* go项目存放目录:D:\\development\\jetbrains\\goland\\workspace,并且此目录下含有bin、src、pkg三个文件夹,src文件夹用来存放项目代码
当引入module时,首先在GOROOT的src目录下查找,然后再GPOPATH的src目录下查找

(2)GOLang环境配置
* 在D:\\development\\jetbrains\\goland\\workspace\\src目录下新建项目GO-Player
bin:存放编译后的exe文件
pkg:存放自定义包的目录
src:存放项目源文件的目录

* 按如下指令进行配置

* 可在Settings中选择SDK和添加GOPATH

(3)测试
* models:Student.go

* main:hello.go
~~~Go
package main
import (
//"./models" //相对路径
"Go-Player/src/ademo/models" //根据GOPATH找
//根据GOPATH:D:\development\jetbrains\goland\workspace,在其src目录下查找
//即GOPATH/src/Go-Player/src/ademo/models
"fmt"
)
func main() {
stu := models.Student{
Name: "张三",
}
fmt.Println(stu)
~~~
此篇文章仅介绍网上大部分GOPATH版本。Go语言Hello World都只简单地介绍了GOPATH版本。但是从Go的1.11版本之后,已不再推荐使用GOPATH来构建应用了。也就是说GOPATH被认为是废弃的,错误的做法。
### 4、一些踩坑经验
当你开启了[GO111MODULE](https://www.cnblogs.com/pu369/p/12068645.html),仍然使用GOPATH模式的方法,在引入自定义模块时会报错。go mod具体使用将在下一篇介绍
`GO111MODULE` 有三个值:`off`, `on`和`auto(默认值)`。
* `GO111MODULE=off`,go命令行将不会支持module功能,寻找依赖包的方式将会沿用旧版本那种通过vendor目录或者GOPATH模式来查找。
* `GO111MODULE=on`,go命令行会使用modules,而一点也不会去GOPATH目录下查找。
* `GO111MODULE=auto`,默认值,go命令行将会根据当前目录来决定是否启用module功能。这种情况下可以分为两种情形:
* 当前目录在GOPATH/src之外且该目录包含go.mod文件
* 当前文件在包含go.mod文件的目录下面。
> 当modules 功能启用时,依赖包的存放位置变更为`$GOPATH/pkg`,允许同一个package多个版本并存,且多个项目可以共享缓存的 module。
(1)使用了了相对路径:**import "./models"**
* **报错:build command-line-arguments: cannot find module for path \_/D\_/dev这里后面一堆本地路径**
这是因为在go module下 你源码中 impot …/ 这样的引入形式不支持了, 应该改成 impot 模块名/ 。 这样就ok了
(2)使用结合了GOPATH的形式:**import "Go-Player/src/ademo/models"**
于是我们把上面的import改成了结合GOPATH的如上形式
* **报错:package Go-Player/src/ademo/models is not in GOROOT D:/development/go/src/GPlayer/src/ademo/models**
(3)彻底解决方法:用go env -u 恢复初始设置
不再使用go mod:
* **go env -w GO111MODULE=off 或者 go env -w GO111MODULE=auto**
* ******go env -u GO111MODULE**
区别在于,如果**GO111MODULE=on或者auto,**在go get下载包时候,会下载到**GOPATH/pkg/mod**,引入时也是同样的从这个目录开始。如果这行了上述命令,那么**在**go get下载包时候,会下载到**GOPATH/src**目录下
本文仅介绍Hello world(GOPATH版),虽然此种方法不推荐使用,但是初学者在使用的时候仍会遇到很多问题。后续将介绍如何使用Go Module版
- go入门
- go基础
- go语言介绍
- go语言主要特性
- Golang内置类型和函数
- init函数和main函数
- 下划线
- iota
- 字符串
- 数据类型:数组与切片
- 数据类型:byte、rune与字符串
- 变量的5种创建方式
- 数据类型:字典
- 指针
- 数据类型:指针
- 类型断言
- 流程控制:defer延迟执行
- defer陷进
- 异常机制:panic和recover
- go函数
- go方法
- go依赖管理
- 轻松搞懂goroot与gopath区别
- 使用go module导入本地包的方法教程详解
- 读取用户的输入
- 文件读写
- 文件拷贝
- 从命令行读取参数
- JSON 数据格式
- 4 种常见JSON 格式数据解码
- XML 数据格式
- 用 Gob 传输数据
- Go 中的密码学
- 学习资料建议
- 深入结构体
- 测试
- 单元测试
- 常用标准库
- fmt
- time
- flag
- log
- IO操作
- 文件读取
- strconv
- template
- http
- context
- json
- 从文件中反序列化json对象
- xml
- go proxy 设置
- 面向对象
- 结构体
- struct能不能比较
- 接口
- make和new的区别
- go进阶
- Slice底层实现
- 闭包与递归
- 空接口
- 反射
- 接口中的“坑”
- 反射三定律
- 结构体里的tag
- 并发编程
- 初识Go 协程:goroutine
- go协程:管道
- 任务和master-锁实现和通道实现
- 惰性生成器的实现
- runtime包
- Goroutine池
- 定时器
- 并发安全和锁
- Sync
- 原子操作(atomic包)
- GMP 原理与调度
- 爬虫案例
- 邮件发送
- Godoc 安装与使用
- test
- 如何测试
- 基准测试
- 数组与切片
- 结构体,方法和接口
- Map实现原理
- 自定义error
- 网络编程
- socket编程
- 互联网协议
- tcp 服务器
- tcp编程
- UDP编程
- TCP黏包
- http编程
- websocket编程
- 设计模式
- 设置模式6大原则
- 创建型模式
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
- 创建者模式
- 原型模式
- 单例模式
- 结构性模式
- 外观模式
- 适配器模式
- 代理模式
- 组合模式
- 享元模式
- 装饰模式
- 桥模式
- 行为型模式
- 中介者模式
- 观察者模式
- 命令模式
- 迭代器模式
- 模板方法模式
- 策略模式
- 状态模式
- 备忘录模式
- 解释器模式
- 职责链模式
- 访问者
- rpc
- Golang内存分配逃逸分析
- 面试题汇总
- 信号量的原理与使用
- 如何让在强制转换类型时不发生内存拷贝
- Go 如何利用 Linux 内核的负载均衡能力
- 性能优化:Go Ballast 让内存控制更加丝滑
- unsafe包详解
- go实战
- Go语言中编码规范
- json如何转为struct对象
- cobra
- 通过go mod模式创建cobra项目
- gorm
- gocache
- zap日志库
- echart
- web技术
- niugo
- context回调实现原理
- 认证与授权
- oauth2.0的4种实现方式
- IRIS
- 安装
- 入门
- 自定义http错误
- 基本HTTP API
- 中间件
- session
- websocket
- mvc
- cookie使用
- Casbin
- CORS跨域资源共享
- csrf防御
- jwt
- 限制HTTP请求次数的中间件Tollbooth
- 文件服务
- 基础使用
- 文件下载
- hero依赖注入与结构体转化
- hero基础
- 网络教程
- gin
- viper
- 在 5 分钟之内部署一个 Go 应用(Supervisor )
- go如何正常go get导入包
- 杂项
- 开源许可证
- 算法
- 洗牌算法
- 经典算法
- 基排序
- 冒泡排序
- 选择排序算法
- 二叉树
- 堆排序
- 快速排序
- 二分查找
- 图算法
- 有向图结构实现
- 拓扑排序
- 一致性hash算法
- 前缀树(字典树)
- 算法实现
- 斐波拉契
- 加密算法
- 简单可逆加密
- DH密钥交换(Diffie–Hellman key exchange)算法
- 代码实现
- Polybius密码(棋盘密码
- xor加密算法
- go应用
- 调试
- 构建并运行
- 包别名
- 类型转换
- error错误的2种处理方式
- 使用defer实现代码追踪
- 计算函数执行时间
- 通过内存缓存来提升性能
- make和new
- 关闭的channel可以读取数据吗
- 如何优雅的关闭channel
- channel应用场景
- map相关问题
- Go 面向包的设计和架构分层
- 设计模式实战
- 模板模式
- 责任链模式
- 组合模式实战
- 观察者模式实战
- 状态模式实战
- 区块链
- 构建一个区块链 -- Part 1: 基本原型
- 构建一个区块链 -- Part 2: 工作量证明
- 构建一个区块链 -- Part 3:持久化和命令行接口
- 从0到精通
- go常用命令
- 获取命令行参数
- http服务
- 基础
- struct 5种实例化
- md5
- Go Protobuf入门
