Go(8)--工程管理

1. 编程环境

1.1 工程结构

1.1.1 环境变量

  • $GOROOT

      $GOROOTGo的安装根目录。

  • $GOPATH

      $GOPATHGo语言编程的工作目录。

  • GOBIN

      $GOBIN是带有main函数的源程序执行go install时生成的可执行程序的安装目录,默认是$GOPATH/bin

  • GOOS和GOARCH

      $GOOS用来设置目标操作系统,$GOARCH用来设置目标平台的 CPU 体系结构。这两个参数多用在交叉编译。

      使用go env命名查看Go的编程环境
在这里插入图片描述

1.1.2 工作目录

      $GOPATH变量所指定的目录称为Go的工作目录,$GOPATH可以配置多个目录,工作目录有相同的目录结构,内含三个子目录:

在这里插入图片描述

      src是工程源码所在目录,一般src下的第一层目录是工程根目录,工程根目录一般采用公司的域名+工程名或用户名的形式,比如常见的GitHub上的工程源代码组织形式:

# 如下都是工程根目录
$GOPATH/src/github.com/github/
$GOPATH/src/github.com/golang/

      工程根目录下才是工程各个项目的目录,项目目录下可以是其源码文件和各种包的源码。例如$GOPATH/src/github.com/github/gh-ost$GOPATH/src/github.com/github/GitHub工程根目录,gh-ost是具体的项目目录,gh-ost内是该项目的源代码和包。

      $GOPATH环境变量可以配置多个目录,使用go get下载第三方包时,默认会将包下载到$GOPATH的第一个目录。

1.2 交叉编译

  • Go 1.4 及以前版本

      在 Go 1.4 及以前版本中,要在当前平台构建一个目标平台的编译环境,然后才能通过设置 GOOSGOPATH进行交叉编译。

# 进入 Go 源码目录
$ cd /usr/local/go/src

# 在 linux 下构建 Windows 交叉编译环境
$ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 ./make.bash

# 交叉编译
$ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build xxx.go
  • Go 1.5 及以后版本
          只需要设置 GOOSGOARCH 变量就可以轻松进行交叉编译。

      编译成Linux目标文件:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build xxx.go

      编译成windows目标文件:

CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build xxx.go

2. 命名空间和作用域

2.1 命名空间

      一个标识符可以在多个命名空间中定义,它在不同命名空间中的含义是互不干扰的。

      Go语言处理包级别的显式的命名空间,还有隐式的命名空间。函数、方法、以及ifforswitch等和“{}”一起构成一个个代码块,代码块可以嵌套,每一个代码块都构成一个隐式的命名空间。

      不同命名空间可以声明相同的标识符,所以不同的隐式的命名空间同样允许声明相同的标识符(包括变量),这里就有变量覆盖的问题。

2.2 作用域

      作用域可以理解为变量的作用范围。Go 语言是静态作用域语言,及变量的作用域不依赖程序执行时的因素,变量的作用域在编译器就能确定。

      Go 语言有三种类型的作用域:

  • 全局作用域

      在任何地方都可以访问的标识符,称其有全局作用域。在 Go 语言中,全局作用域有两类:

            (1)Go 语言内置的预声明标识符,他们有全局作用域,在任意包内可见。

            (2)Go 语言包内以大写字母开头的标识符,他们有全局作用域,在任意命名空间都可见。

  • 包内作用域

      在 Go 语言包内定义的以小写字母开头的标识符,他们在本包可见,在其他包不可见,这些标识符具有包作用域。

  • 隐式作用域

      每个代码块内定义的变量称为局部变量,这些局部变量只在当前代码块内可见,其作用域属于当前代码块的隐式作用域。

2.3 变量覆盖

      Go 编译器能够解析变量名到引用实体采用的是从里到外的搜索模式,里层的局部变量能够覆盖外层变量,使得外层的同名变量不可见,这种现象称为变量覆盖。

3. 包的基本概念

      Go 语言是使用 包来组织源代码的,并实现命名空间的管理。任何源代码文件必须属于某个包。

3.1 基本概念

      一般包的名称就是其源文件所在目录的名称,虽然 Go 没有强制包名必须和其所在的目录同名,但还是建议包名和所在的目录同名,这样结构更加清晰。

      包的定义是不包括目录路径的,但是包的引用一般是全路径引用。比如在$GOPATH/src/a/b/下定义一个包 c,在包 c 的源码中只需要声明为package c,而不是声明为package a/b/c,但是在importc时,需要带上路径import "a/b/c"

      包的习惯用法:

  • 包名一般是小写的,使用一个简短的命名
  • 包名一般要和所在的目录同名
  • 包一般放到公司的域名目录下,这样能保证包名的唯一性,便于共享代码。

3.2 包引用

      标准包的源码位于$GOROOT/src/下面,标准包可以直接引用。自定义包和第三方包的源码必须放到$GOPATH/src目录下才能被引用。

      包引用路径

      包的引用路径有两种写法,一种是全路径,另一种是相对路径。

  • 全路径引用

      包的绝对路径就是$GOROOT/src$GOPATH/src后面包的源码的全路径,比如下面的包引用。

import "lab/test"
import "database/sql/driver"
import "database/sql"

      test包是自定义的包,其源码位于$GOPATH/src/lab/test目录下。sqldriver包分别位于$GOROOT/src/database/sql$GOROOT/src/database/sql/driver下。

  • 相对路径引用

      相对路径只能引用$GOPATH下的包,标准包的引用只能使用全路径引用。比如下面两个包的路径分别为$GOPATH/src/llab/a$GOPATH/src/llab/b,假设b引用了a包,则可以使用相对路径引用方式。

// 相对路径引用
import "../a"

// 绝对路径引用

      包引用格式

      包引用有四种格式

  • 标准引用方式
	import "fmt"
  • 别名引用方式
	import F "fmt"
  • 省略方式
	import . "fmt"

      此时相当于把包fmt的命名空结直接合并到当前程序的命名空间中,使用fmt包内可导出的元素可以不用前缀fmt.,直接引用。

  • 仅执行包初始化init函数

      使用标准格式引用包,但是代码中没有使用包,编译器会报错。如果包中有init初始化函数,则通过import _ "packageName"这种方式引用包,仅执行包的初始化函数,即使包没有init初始化函数,也不会引发编译器报错。

      注意

  • 一个包可以有多个init函数,包加载会执行全部的init函数,但并不能保证执行顺序。
  • 包不能出现环形引用。比如包a引用了包b,包b引用了包c,包c引用了包a,则编译不能通过。
  • 包的重复引用时允许的。比如包a引用了包b和包c,包b和包c都引用了包d。这种场景相当于重复引用了d,这种情况是允许的,并且Go编译器保证dinit函数只执行一次。

3.3 包加载

      在执行main.main之前,Go 引导程序会先对整个程序的包进行初始化。真个执行流程如图所示:

在这里插入图片描述
      单个包的初始化过程如上图,先初始化常量,然后是全局变量,最后执行包的init函数。

4. 第三方包管理

      项目中经常会引用大量第三方库,使用go get可以轻松轻松下载并安装第三方的库到本地。但是如果第三方库更新,并行新版本和旧版本不兼容。此时旧需要对第三方库进行更精细的管理,即对第三方库的版本做更精确的管控。

4.1 vendor

      vendor将原来放在$GOPATH/src的第三方包放到当前工程的vendor目录进行管理,多个工程可以独立地管理自己第三方依赖包,他们直接不会项目影响。vendor将原来包共享模式转换为每个工程独立了地维护模式,vendor的另一个好处是保证了工程目录下代码地完成行,将工程代码赋值到其他 Go 扁你环境,不需要再去下载第三方包,直接就能编译。

      Go1.5 需要手动设置环境变量GO15VENDOREXPERIMENT=1,Go 编译器才能引用verdorGo1.6默认开启vendor目录。

      整个查找第三方包的流程如下:

  1. 如果当前包下有vendor目录,则从其下查找第三方的包,如果没有找到,继续执行下一步操作。
  2. 如果当前包下没有vendor目录,则向上主机目录查找vendor目录,知道找到$GOPATH/src下的vendor目录,只要找到vendor目录,就去查找第三方包,如果没有继续执行下一步操作。
  3. GOPATH 下面查找依赖包
  4. GOROOT 下面查找依赖包

      go get -u更新第三方包,默认是将工最新版本拉取到本地。而vendor无法进行版本控制,为解决该问题,引入了dep

4.2 dep

      go get能够快速拉取一个第三方的包,如果是正式工程项目,则建议使用dep进行包管理。

因网络原因,无法进行下载,请自行下载学习。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值