Go36-1

源码安装工具 go install

源码文件通常会被放在某个工作区的 src 子目录下。
那么在安装后如果产生了归档文件,就会放进该工作区的 pkg 子目录;如果产生了可执行文件,就可能会放进该工作区的 bin 子目录。

归档文件存放的位置

安装某个代码包而产生的归档文件是与这个代码包同名的,扩展名是 .a。放置它的相对目录就是代码包的导入的父级文件夹的路径。
执行命令:

go install github.com/labstack/echo

生成的归档文件的相对目录就是 github.com/labstack , 文件名为 echo.a。
上面的相对路径是在pkg目录下的,并且中间还有一层目录,目录的名称是操作系统有关的,叫做平台相关目录。目录名称是操作系统、下划线和计算架构的代号组成。比如:linux_amd64、windows_amd64。
因此上面的代码存放的相对路径是:pkg/windows_amd64/github.com/labstack/echo.a
上述内容也可以去Go安装的路径下查看,比如我的Win10系统,把Go安装在了D盘的根目录下。于是在 D:\Go\pkg\windows_amd64 目录下就可以看到所有标准库的归档文件。

构建 go build 和安装 go install

构建使用命令go build,安装使用命令go install。构建和安装代码包的时候都会执行编译、打包等操作,并且这些操作生成的任何文件都会先被保存到某个临时的目录中。
源码文件分为三种,它们都有着不同的用途和编写规则:

  • 命令源码文件,声明属于main包并且包含一个main主函数(应该还是个无参数无返回值的函数),所以可以被直接执行
  • 库源码文件,不含主函数的包文件,不能被直接运行,它仅用于存放程序实体。
  • 测试源码文件,名称以_test.go结尾的源文件。不是下面要讲的,略过。

构建 go build

如果构建的是库源码文件,那么操作的结果文件只会存在于临时目录中。这里的构建的主要意义在于检查和验证。
也就是构建了临时目录,然后就丢弃了。如果有问题就会报出来,如果没问题就相当于一顿操作后什么都没变化,就是上面说的加和验证。
如果构建的是命令源码文件,那么操作的结果文件会被搬运到那个源码文件所在的目录中。
一般构建就是用来做这个事情的。

安装 go install

安装操作会先执行构建,然后还会进行链接操作,并且把结果文件搬运到指定目录。
如果安装的是库源码文件,那么结果文件会被搬运到它所在工作区的 pkg 目录下的某个子目录中。
如果安装的是命令源码文件,那么结果文件会被搬运到它所在工作区的 bin 目录中,或者环境变量GOBIN指向的目录中。

小结

命令源码文件,通过构建或安装都可以完成编译,只是生成的可执行文件的目录不同。一般就用构建了,可以带参数指定位置。
库源码文件,只有通过安装才能在pkg中生成包文件。
一般就是构建源码文件。库文件的话就是进行安装。

go build 命令

在运行go build命令的时候,默认不会编译目标代码包所依赖的那些代码包,如果归档文件已经存在的话。如果被依赖的代码包的归档文件不存在,或者源码文件有了变化,那它还是会被编译。常用参数说明:

  • -a : 可以强制编译依赖的代码包
  • -i : 不但要编译依赖的代码包,还要安装它们的归档文件
  • -x : 查看go build命令具体执行了哪些操作
  • -n : 同上,只查看操作,但是不实际执行
  • -v : 可以看到go build命令编译的代码包的名称。搭配-a参数使用时很有用

go get 命令

命令go get会自动下载代码包,并把它们安装到环境变量GOPATH包含的第1工作区的相应目录中。如果存在环境变量GOBIN,那么仅包含命令源码文件的代码包会被安装到GOBIN指向的那个目录。常用参数说明:

  • -u : 下载并安装代码包,不论是否已存在
  • -d : 只下载代码包,不安装代码包
  • -fix : 在下载代码包后先运行一个用于根据当前Go语言版本修正代码的工具,然后再安装代码包
  • -t : 同时下载测试所需的代码包
  • -insecure : 允许通过非安全的网络协议下载和安装代码包。比如:HTTP。

包的依赖管理

go get命令中并没有提供依赖管理的功能。目前GitHub上有很多提供这类功能的第三方工具,比如glide、gb以及官方出品的dep、vgo等等,在它们的内部大都是直接使用go get实现的。

自定义代码包远程导入路径

如果你想把你编写的(被托管在不同的代码托管网站上的)代码包的远程导入路径统一起来,或者不希望让你的代码包中夹杂某个代码托管网站的域名,那么你可以选择自定义你的代码包远程导入路径。这种自定义的实现手段叫做“导入注释”。
比如代码实际存储的位置是:github.com/golang/sync/
但是安装的时候实际使用的命令是:go get golang.org/x/sync。这里就隐藏了github.com的域名,以及后面的部分路径golang。

导入注释

导入注释必须出现在源码文件的代码包声明语句的右边,是一条单行注释。被双引号包裹的是一个符合导入路径语法规则的字符串。下面是 github.com/golang/sync 下 semaphore/semaphore.go 里的导入注释:

package semaphore // import "golang.org/x/sync/semaphore"

这样加入导入注释后,就无法用github的地址来下载这个包了。但是也无法用自定义的路径来下载这个包,应该自定义的路径的网址还不能响应这个请求

编写网站的处理请求

编写一个可处理HTTP请求的程序。将对这个url响应的请求头中加入如下的一行内容:

<meta name="go-import" content="golang.org/x/sync git https://github.com/golang/sync">

这行内容会被视为HTML文档的元数据。这个就是go get命令的文档中要求的写法。它的模式是这样的:

<meta name="go-import" content="import-prefix vcs repo-root">

content属性中的import-prefix的位置上填入自定义的远程代码包导入路径的前缀。而vsc代表与版本控制系统有关的标识,比如git。至于repo-root,它应该是与该处理程序关联的路径对应的Github网站的URL,即实际网址。

这么做的好处是,可以强化你的品牌,而不是某个代码托管网站的。顺便还可以隐藏掉用户ID,也就是域名后的部分路径。
最主要的是,使你的代码包导入路径整齐划一,如果代码包分散在不同的远程路径的话。

原文地址:http://blog.51cto.com/steed/2337417

时间: 2024-11-06 11:42:33

Go36-1的相关文章

打算听的歌

最喜欢的一首: Everybody konws i love you 1 Amy Diamond - It's My Life2 Angela Ammons - Always Getting Over You3 Angela Ammons - Big Girl4 ashley tisdale - love me for me - 音乐咖啡厅5 Atomic Kitten - If You Come To Me6 Atomic Kitten - Nothing In The World7 Brit

Go36-3-代码包

把代码拆分到多个文件 如果代码太复杂,就可以把代码写在多个源码文件里.或者是其他代码包中(这个后面讲) 代码示例 下面是程序的主体,但是其中调用了square()函数,这个函数并没有声明: // Go36/article03/example01/demo.go package main import ( "flag" "fmt" ) var x int func init() { flag.IntVar(&x, "x", 0, "

Go36-4,5,6-变量

上篇 Go语言中的程序实体包括变量.常量.函数.结构体和接口.Go语言是静态类型的编程语言,所以我们在声明变量或常量的时候都需要指定它们类型,或者给予足够的信息以使Go语言能够推导出它们的类型. 声明变量 声明变量的方式: var name string var name = "Adam" name := "Bob" // 短变量声明 第三种短变量声明只能在函数体内部使用. 知识点 类型推断 后两种在声明的同时还进行了赋值,没有显示的指定类型,而是利用了Go的类型推

Go36-7-数组和切片

数组和切片 数组(array)类型和切片(slice)类型: 相同:都属于集合类的类型,它们的值都可以用来存储某一种类型的值(或者说元素). 不同:数组的长度是固定的,而切片是可变长的. 长度数组的长度在声明的时候必须确定,并且之后不会再变.长度是其类型的一部分. 比如:[1]string 和 [2]string 是两个不同的类型. 切片的长度是可以随着其中元素的增长而增长的,但是不会随着元素的减少而减少. 底层数组可以把切片看做是对数组的一层简单的封装,每个切片的底层数据结构中,一定会包含一个

Go36-10,11-通道

通道 通道(channel)是Go语言的并发编程模式中重要的一员.通道类型的值本身就是并发安全的,这也是Go语言自带的.唯一一个可以满足并发安全性的类型. 使用通道 声明一个通道类型变量,需要确定该通道类型的元素类型,这决定了可以通过这个通道传递什么类型的数据. 初始化通道,需要用到Go语言的内建函数make.make函数除了必须接收类型字面量作为参数,还可以接收一个int类型的参数.第二个参数是可选的,表示通道的容量. 通道的容量,指通道最多可以缓存多少个元素: 当容量为0时,未设置第二个参数

Go36-15-指针

指针 之前已经用到过很多次指针了,不过大多数时候是指指针类型及其对应的指针值.这里要讲更为深入的内容. 其他指针 从传统意义上说,指针是一个指向某个确切的内存地址的值.这个内存地址可以是任何数据或代码的起始地址,比如,某个变量.某个字段或某个函数. uintptr 在Go语言中还有其他几样东西可以代表"指针".其中最贴近传统意义的当属uintptr类型了.该类型实际上是一个数值类型,也是Go语言内建的数据类型之一.根据当前计算机的计算架构的不同,它可以存储32位或64位的无符号整数,可

Go36-21,22-panic函数、recover函数以及defer语句

panic panic,Go语言的另外一种错误处理方式.严格来讲,它处理的不是错误,而是异常,并且是一种在我们意料之外的程序异常. panic详情 要分析panic详情,首先来生成一个panic.比如在一个切片里,它的长度是5,但是要通过索引5访问其中的元素,这样的访问是不正确的.比如下面这样: func main() { l := []int{1, 2, 3, 4, 5} _ = l[5] } 程序在运行时,会在执行到这行代码的时候抛出panic,提示用户索引越界了.这不仅仅是个提示.当pan

Go36-26-互斥锁与读写锁

从同步讲起 相比于Go语言宣扬的"用通讯的方式共享数据",通过共享数据的方式来传递信息和协调线程运行的做法其实更加主流.本篇就是讨论一些与多线程.共享资源以及同步有关的知识. sync包,就是一个与并发编程关系紧密的代码包.这里"sync"的中文意思就是"同步". 重要的并发编程概念 这里会讲一些重要的并发编程概念:竞态条件.临界区.互斥量.死锁.死锁会在互斥锁里引出. 一旦数据被多个线程共享,那么就很可能会产生争用和冲突的情况.这种情况也被称为

Go36-36,37-字符串

unicode与字符编码 字符编码的问题,是计算机领域中非常基础的一个问题. Unicode编码 Go语言中的标识符可以包含任何Unicode编码可以表示的字母字符.可以直接把一个整数数值转换为一个string类型的值.被转换的整数值应该是一个有效的Unicode码点,否则会显示为一个"?"字符: package main import "fmt" func main() { s1 := '你' // 这是一个字符类型,不是字符串 fmt.Println(int(s

Go36-38,39-bytes包

基本操作 bytes包和strings包非常相似,单从它们提供的函数的数量和功能上看,差别微乎其微. strings包主要是面向Unicode字符和经过UTF-8编码的字符串,而bytes包主要是面对字节和字节切片. bytes.Buffer类型 Buffer类型的用途主要是作为字节序列的缓冲区. bytes.Buffer是开箱即用的.可以进行拼接.截断其中的字节序列,以各种形式导出其中的内容,还可以顺序的读取其中的子序列.所以是集读.写功能与一身的数据类型,这些也是作为缓冲区应该拥有的功能.