GOROOT

golang安装路径。

GOPATH

官方解释,请google。go工作环境中常常用到的一个很重要的环境变量(这种设计类似java)。具体用途:go命令常常需要用到的,如go run,go install, go get等。允许设置多个路径,和各个系统环境多路径设置一样,windows用“;”,linux(mac)用“:”分隔。

在linux(Mac)下,为了方便,一般配置在~/.bash_profile中。

book:~ wukebing$ vi ~/.bash_profile  //编辑

book:~ wukebing$ source ~/.bash_profile //编辑完成后,使立即生效

例如:我的GOPATH设置(MAC下)

export GOPATH=$HOME/workspace/go
export PATH=$PATH:${GOPATH//://bin:}/bin
export GOBIN=

其中,“export PATH=$PATH:${GOPATH//://bin:}/bin”为Linux(Mac)下把每个GOPATH下的bin都加入到PATH中。

当存在多个路径时,好像优先采用第一个路径。这个无关紧要了,只有需要的第三方包(库)都能正确下载和使用就ok了。

GOBIN

go install编译存放路径。不允许设置多个路径。可以为空。为空时则遵循“约定优于配置”原则,可执行文件放在各自GOPATH目录的bin文件夹中(前提是:package main的main函数文件不能直接放到GOPATH的src下面。

go环境查看

用go env 可查看当前go环境变量。

GOPATH目录结构

goWorkSpace  // (goWorkSpace为GOPATH目录)
-- bin // golang编译可执行文件存放路径,可自动生成。
-- pkg // golang编译的.a中间文件存放路径,可自动生成。
-- src // 源码路径。按照golang默认约定,go run,go install等命令的当前工作路径(即在此路径下执行上述命令)。

go目录结构1:

project1 // (project1添加到GOPATH目录了)
-- bin
-- pkg
-- src
-- models // package
-- controllers // package
-- main.go // package main[注意,本文所有main.go均指包main的入口函数main所在文件]
 project2 // (project2添加到GOPATH目录了)
-- bin
-- pkg
-- src
-- models // package
-- controllers // package
-- main.go // package main
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

package main文件直接在GOPATH目录到src下。

使用go build可以在src文件夹下编译生成名为“src”的可执行文件。这是golang默认约定。一般我个人不怎么用这个命令。因为它会生成可执行文件在src目录下面。

我一般用:go get 和 go install。

go get [main.go所在路径]

参数 [main.go所在路径]:可选。相对GOPATH/src路径。 缺省是.(src自己)。可指定src下面的子文件夹路径。 
go get会做2件事:1. 从远程下载需要用到的包。2.执行go install。(从这里也可以看出golang处处为了简洁而遵循的“约定优于配置”原则)

go install [main.go所在路径]

参数 [main.go所在路径]:可选。 相对GOPATH/src路径。缺省是.(即当前所在目录或工作目录)。可指定src下面的子文件夹。 
go install编译生成名称为[main.go父文件夹名]的可执行文件,放到GOBIN路径下。当GOBIN为空时,默认约定是:生成的可执行文件放到GOPATH/bin文件夹中。产生的中间文件(.a)放在project/pkg中(没有变化时,不重新生成.a)。

我们再看此go目录结构1,执行go install(以及go get的第二阶段go install)会报错:

注意:如果不用额外方式改变环境变量(公司目前用的是sh脚本编译),是编译不过的。报错:can’t load package: package .: no buildable Go source files in *

解决方法1: 
曾经我也因为这个错误感到迷惑,认为所有都环境变量都没有问题。网上也没怎么看到直接明确都解答。看了一些帖子后,触类旁通,设置了GOBIN环境变量后解决。(好吧,我至今也没有完整读过英文官方文档。这种默认约定,官方文档上应该有。)

此解决方法有个弊端,多个project会导致多个GOPATH目录。多个project下的目录结构和包一致的话,直接编译会导致编译问题。因为go优先使用第一个GOPATH目录,导致编译冲突。(当然,你也可以每次手工或脚步修改GOPATH环境变量,感觉很麻烦。)不建议多个project直接设置到茫茫多的GOPATH中。当然有解决方法2,我认为是标准合理的解决方法,就是下面go目录结构2了。

go目录结构2:

goWorkSpace     // goWorkSpace为GOPATH目录
-- bin
-- myApp1 // 编译生成
-- myApp2 // 编译生成
-- myApp3 // 编译生成
-- pkg
-- src
-- common 1
-- common 2
-- common utils ...
-- myApp1 // project1
-- models
-- controllers
-- others
-- main.go
-- myApp2 // project2
-- models
-- controllers
-- others
-- main.go
-- myApp3 // project3
-- models
-- controllers
-- others
-- main.go

一个solution里面的多个project或工具组件都并列放在GOPATH的src下,如myApp1,myApp2,myApp3,common utils。 
这时,GOBIN可以为空,编译时,可以如下: 
go install myApp1 或 go get myApp1 
go install myApp2 或 go get myApp2 
go install myApp3 或 go get myApp3

这时才是大家都认为的,把可执行程序myApp1、myApp2、myApp3生成在goWorkSpace/bin下面。多个GOPATH也就有了上面的“把每个GOPATH下的bin都加入到PATH中”。

提示:相同结构的project下同名包怎么办? 
有同事在初学时,习惯按照go目录结构1,了解到go目录结构2后(以为仅仅是把main放到了子文件夹,其他controllers等包结构不变),有这样的疑惑。他们原来就有这样的问题,同时把go目录加入到GOPATH后,编译就出现问题,因为包名和路径相同(相对GOPATH下的src),go只会优先查找第一个符合的GOPATH)。只会每次编译时手工修改GOPATH,或写脚本编译。(我看着就觉得累,还徒增脚本维护烦恼。)

解决方案就是:除了通用的,公有的工具、组件外,属于各个project自己的东西,统统随着main.go一起移到project目录下。go目录结构2就是这样的。 
导入各个project下的controllers方法:import myApp1/controllers,import myApp2/controllers这样的。go的import查找的是包的路径,并不是包名。你只用告诉go,你的包都放在哪了,go会从这些路径下查找有没有所需要的包。只是大家一般习惯包名和文件夹名相同,容易误解。只需要注意,一个文件夹下只允许有一个包名,允许有子文件夹定义不同的包。 
import 采用的是相对路径写法:路径是 相对GOROOT和GOPATH下的src。

也可以设置GOBIN,而且这时,由于可执行文件名称不同,也不大容易产生覆盖(需要避免的时多个GOPATH用相同的“myApp”project名称。)

具体的还是看个人喜好和实际情况。我个人本地的环境大致是:

dir
-- goWorkSpace1 // 主要是为了区分自己的鼓捣的一些东西和工作上的项目
-- goWorkSpace2
-- bin
-- pkg
-- src
-- myApp1
-- .git
-- models
-- controllers
-- main.go
-- myApp2
-- .git
-- models
-- controllers
-- main.go
-- myApp3
-- .git
-- models
-- controllers
-- main.go

也就是我本地是有多个GOPATH路径的dir/goWorkSpace1、dir/goWorkSpace2。 
注意:GOPATH目录和GOPATH下的src不应该添加到源代码管理中,而是各个project目录myApp1、myApp2、myApp3各自时独立的进行源代码管理

我一般不设置GOBIN,把每个GOPATH下的bin都加入到PATH中。

摘录自:http://blog.csdn.net/Alsmile/article/details/48290223

gopath基础概念的更多相关文章

  1. 【Machine Learning】机器学习及其基础概念简介

    机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  2. TCP/IP基础概念及通信过程举例

    TCP/IP基础概念及通信过程举例 出现 上个世纪60年代,由于中央集中式网络的容灾性较弱,以美国国防部为中心的一家组织研究出分组交换网络.后来为了验证分组交换技术的实用性,ARPANET出现了,并且 ...

  3. Jmeter基础之---jmeter基础概念

    Jmeter基础之---jmeter基础概念 JMeter 介绍: 一个非常优秀的开源的性能测试工具. 优点:你用着用着就会发现它的重多优点,当然不足点也会呈现出来. JMeter 介绍: 一个非常优 ...

  4. 快速入门系列--WCF--01基础概念

    转眼微软的WCF已走过十个年头,它是微软通信框架的集大成者,将之前微软所有的通信框架进行了整合,提供了统一的应用方式.记得从自己最开始做MFC时,就使用过Named Pipe命名管道,之后做Winfo ...

  5. 理解 angular2 基础概念和结构 ----angular2系列(二)

    前言: angular2官方将框架按以下结构划分: Module Component Template Metadata Data Binding Directive Service Dependen ...

  6. JavaBean 基础概念、使用实例及代码分析

    JavaBean 基础概念.使用实例及代码分析 JavaBean的概念 JavaBean是一种可重复使用的.且跨平台的软件组件. JavaBean可分为两种:一种是有用户界面的(有UI的):另一种是没 ...

  7. RabbitMQ基础概念详细介绍

    http://blog.csdn.net/column/details/rabbitmq.html 转至:http://www.ostest.cn/archives/497 引言 你是否遇到过两个(多 ...

  8. linux设备驱动归纳总结(二):模块的相关基础概念【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-59415.html linux设备驱动归纳总结(二):模块的相关基础概念 系统平台:Ubuntu 10 ...

  9. linux设备驱动归纳总结(一)内核的相关基础概念【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-59413.html linux设备驱动归纳总结(一):内核的相关基础概念 xxxxxxxxxxxxxx ...

随机推荐

  1. Win32环境下代码注入与API钩子的实现(转)

    本文详细的介绍了在Visual Studio(以下简称VS)下实现API钩子的编程方法,阅读本文需要基础:有操作系统的基本知识(进程管理,内存管理),会在VS下编写和调试Win32应用程序和动态链接库 ...

  2. centos7 挂载exfat格式的u盘

    下载 两个包 rpm -ivh http://download1.rpmfusion.org/free/el/updates/7/x86_64/f/fuse-exfat-1.2.8-1.el7.x86 ...

  3. Python的功能模块[0] -> wmi -> 获取 Windows 内部信息

    wmi模块 / wmi Module WMI (Windows Management Instrumentation) 模块可用于获取 Windows 内部信息.该模块需要 win32com 的支持, ...

  4. Codeforces 1025D Recovering BST

    这个题被wa成傻逼了.... ma[i][j]表示i,j能不能形成一条直接作为排序二叉树的边,n^3更新维护ma即可,按说应该是要爆复杂度的,数据玄学吧.. #include<iostream& ...

  5. luogu P1340 兽径管理

    题目描述 约翰农场的牛群希望能够在 N 个(1<=N<=200) 草地之间任意移动.草地的编号由 1到 N.草地之间有树林隔开.牛群希望能够选择草地间的路径,使牛群能够从任一 片草地移动到 ...

  6. [CF526G]Spiders Evil Plan

    题目大意: 给出一个$n(n\leq 10^5)$个结点的带边权的树,$q(q\leq 10^5)$个询问,每次询问用$y$条路径覆盖整棵树且覆盖$x$至少一次,最多能覆盖的道路长度是多少? 强制在线 ...

  7. CENTOS设置MYSQL字符集

    CENTOS设置MYSQL字符集 show variables like 'character_set%'; vim etc/my.cnf 修改成如下: [client] port=3306 sock ...

  8. MailKit---发送邮件

    一封最复杂的电子邮件的基本情况为:含有邮件正文和邮件附件,邮件正文可以同时使用HTML格式和普通文本格式表示,并且HTML格式的正文中又引用了其他的内嵌资源.对于这种最复杂的电子邮件,可以采用如图所示 ...

  9. Vue的常用指令v-if, v-for, v-show,v-else, v-bind, v-on

    Vue.js的指令是以v-开头的,它们作用于HTML元素,指令提供了一些特殊的特性,将指令绑定在元素上时,指令会为绑定的目标元素添加一些特殊的行为,我们可以将指令看作特殊的HTML特性(attribu ...

  10. 利用jquery.form.js实现将form提交转为ajax方式提交的方法(带上传的表单提交)

    提供一种方法就是利用jquery.form.js. (1)这个框架集合form提交.验证.上传的功能. 核心方法 -- ajaxForm() 和 ajaxSubmit() $('#myForm').a ...