Go语言程序设计及实例 课件 第5章 源代码组织与管理_第1页
Go语言程序设计及实例 课件 第5章 源代码组织与管理_第2页
Go语言程序设计及实例 课件 第5章 源代码组织与管理_第3页
Go语言程序设计及实例 课件 第5章 源代码组织与管理_第4页
Go语言程序设计及实例 课件 第5章 源代码组织与管理_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第5章

源代码组织与管理Go语言的包01包的概念包的概念Go语言的包采用目录树的组织形式,一般包的名称就是其源文件所在的目录名,虽然Go并不强制包名必须与其所在的目录同名,但还是建议读者在开发项目时取相同的名字,这样可使项目结构更清晰。此外,在给包取名时还应遵守下面两个习惯:(1)包名一般全是小写,并尽可能地用一个有意义的简短命名。(2)实际工作中,包一般放到公司的域名目录下,这样既能保证包名的唯一性,又便于代码共享,比如一家名为easybooks公司所开发项目的包一般放到“src\\项目名”目录下。02包的工作目录1.Go环境变量2.目录结构包的工作目录1.Go环境变量在Go编程环境中,包的工作目录与几个重要的环境变量息息相关,先介绍一下。(1)$GOROOT这是Go语言安装的根目录。在Windows下安装包会自动设置,默认是C:\ProgramFiles\Go,如果不是安装在这个默认目录,则必须显式地设置$GOROOT环境变量。(2)$GOPATH这是Go程序开发的工作目录,类似于Java语言的工作区(Workspace)。Windows下默认是C:\Users\<用户名>\go,其中“用户名”为操作系统当前的登录用户名。(3)$GOBIN这是带有main函数的源程序执行goinstall命令时生成的可执行程序安装目录,默认是$GOPATH\bin。如果想在任何路径执行安装的程序,可以将$GOBIN添加到Windows系统环境变量Path中。包的工作目录(4)$GOOS与$GOARCH$GOOS用来设置目标操作系统,$GOARCH用来设置目标平台的CPU体系结构。这两个变量主要用在Go程序跨平台的交叉编译中,一般不用设置。以管理员身份打开Windows命令行,用goenv命令可查看Go编程环境当前各变量的值,如图。包的工作目录2.目录结构$GOPATH环境变量所指定的目录就是Go程序包默认的工作目录。在用传统方式开发Go项目时,会在工作目录下创建3个子目录,如图。包的工作目录(1)src目录包含了组成各种包的源代码。通常在src下的第一层是根目录(一般是公司域名),根目录下才是各个项目的目录,项目目录下可以是其源代码文件及各种包,这是一种推荐的代码组织结构,例如:$GOPATH\src\\grpc其中,“$GOPATH\src\”就是根目录,“grpc”则是具体的项目目录,而grpc内则是该项目的源代码文件和包。(2)pkg目录用于存放各包编译生成的类库。(3)bin目录用于存放包编译或安装后生成的可执行(.exe)文件。其中,src目录必须由用户自己建立用于包含所有的源代码,这是Go的强制规定,而另两个(pkg和bin)目录则无须手动创建,必要时Go命令行工具在构建项目的过程中会自动创建它们。03包的使用1.导入包2.引用路径3.包的加载4.包的作用域包的使用1.导入包用import语句导入包,有4种引用方式,这里以Go的fmt标准库(包)为例说明如下。(1)标准方式import"fmt"这是最常用的一种方式,导入后可以用“fmt.”作为前缀引用包内的可导出元素,如:fmt.Println("Hello,我爱Go语言!@easybooks")(2)别名方式importsay"fmt"相当于给包fmt起了个别名say,用“say.”代替标准的“fmt.”作为前缀引用包内元素,语句写成:say.Println("Hello,我爱Go语言!@easybooks")(3)省略方式import."fmt"这相当于把包fmt的命名空间与当前程序的命名空间直接合并,合并后就可不用前缀直接引用fmt包内元素,简写成:Println("Hello,我爱Go语言!@easybooks")包的使用(4)仅执行包初始化函数当使用标准方式导入了包但是代码中却没有使用此包,编译器会报错,可改用“import_"包名"”这种方式导入包,它仅执行包的init初始化函数,即使包没有初始化函数也不会引发编译器报错,如:packagemainimport_"fmt"funcmain(){ //无代码}包的使用2.引用路径Go语言所有内置标准包的源码都位于$GOROOT\src下,可以直接引用。而自定义或第三方包的源码则必须放到$GOPATH\src目录下才能被引用。引用一个包可以用全路径或相对路径,写法如下。(1)全路径全路径就是包的根路径($GOROOT\src或$GOPATH\src)后面包源码的完整路径,例如,下面这几个包的引用路径:import"/MyBmi/bmi"import"/grpc/peer"import"database/sql/driver"其中,bmi是自定义的包,其源码保存在$GOPATH\src\\MyBmi\bmi目录下;peer是第三方(谷歌开发的gRPC框架)的包,从网络下载的源码位于$GOPATH\src\\grpc\peer下;driver是Go语言内置的包,源码在$GOROOT\src\database\sql\driver下。(2)相对路径比如有两个包:包a的路径是$GOPATH\src\\a,包b的路径是$GOPATH\src\\b,现假设b要引用a包,则可以使用相对路径引用方式,如下:import"../a"相对路径只能用于引用$GOPATH下的包,而标准包的引用只能使用全路径。包的使用3.包的加载程序启动时,在执行入口(main)函数之前,Go的引导程序会先对整个程序中的包进行初始化并逐个加载包,流程如下。(1)引导程序从入口函数导入的包开始,逐级查找包的引用,直到找到没有引用其他包的包,最终生成一个包引用的有向无环图。(2)然后,编译器将有向无环图转换为一棵树,从树的叶子节点开始逐层向上对包进行初始化。(3)对单个包,先初始化其常量,然后是全局变量,最后才执行包的init函数(如果有)。一个包可以有多个init函数,初始化时会执行全部的init函数,但并不能保证执行顺序,所以不建议在一个包中放入多个init函数,而是将需要初始化的逻辑写在一个init函数里。包的使用4.包的作用域作用域(scope)是指程序代码中标识符的名字与实例(内存地址)的绑定保持对应有效的逻辑区间,简言之,就是在多大的范围内可见(能够访问)这个标识符。Go语言是静态作用域语言,其标识符的可见范围不依赖程序运行时的因素,在编译期就能完全确定。Go语言用命名空间(Namespace)来表示标识符的可见范围,一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。这意味着在一个新的命名空间中可定义任意名字的标识符,而不会与其他命名空间的同名标识符发生冲突。包名构成了Go命名空间的一部分,不同的包可看作是一个独立的命名空间,因此在不同包内可以声明相同的标识符。Go语言包内以大写字母开头的标识符(包括变量、常量、函数和方法名、自定义类型、类的属性等),它们具有全局作用域,在任意命名空间内都可见;而包内定义的以小写字母开头的标识符却仅在本包可见,在其他包都是不可见的,这些标识符只具有包内作用域。包的使用【实例5.1】主程序访问同一包内的另一源文件。在$GOPATH\src(笔者的为C:\Users\Administrator\go\src)下建立根目录“”,其下再建一个项目目录“MyBmi”。然后用Windows记事本在项目目录中创建两个Go源文件:human.go与main.go。(1)human.go中定义Human类及其属性和方法(首字母全为小写),代码。(2)main.go作为主程序使用Human类,代码如下:packagemainimport"fmt"funcmain(){ man:=Human{} man.setName("周何骏") man.setHeight(1.73) man.setWeight(60) man.setAge(19) fmt.Println(man.getName(),"BMI指数是",man.bmiCal())}包的使用(3)运行以管理员身份打开Windows命令行,先后执行如下命令:cdC:\Users\Administrator\go\src\\MyBmigorunmain.gohuman.go运行过程如图。包的使用【实例5.2】主程序访问不同包下的另一源文件。(1)在上例所建的项目目录MyBmi下新建一个目录bmi作为包,将源文件human.go放到包中,代码改为。(2)将主程序main.go的代码写成如下:packagemainimport( "fmt" "/MyBmi/bmi" //全路径引用包)funcmain(){ man:=bmi.Human{} man.Name="周何骏" //直接访问Name属性 man.SetHeight(1.73) man.SetWeight(60) man.SetAge(19) fmt.Println(man.Name,"BMI指数是",man.BmiCal())}包的使用(3)运行在Windows命令行下执行:cdC:\Users\Administrator\go\src\\MyBmigorunmain.go运行过程如图。包的使用若将main.go中的语句“man.SetHeight(1.73)”改成“man.height=1.73”,由于height(身高)属性首字母是小写,包外部的程序无法直接访问,运行出错,如图。第5章

源代码组织与管理第三方包01安装第三方包1.获取安装2.编译安装安装第三方包1.获取安装使用goget命令可以通过网络远程获取(或更新)第三方包及其依赖包,自动完成编译和安装,命令格式为:goget-参数带全路径的包名这里的“全路径”指的是包的完整网络访问路径,goget命令据此动态获取远程代码托管平台仓库中的包,目前支持的主要托管平台有Github、Gitee(码云)等。例如:goget-u/golang/protobuf/protoc-gen-go这个命令会自动到Github上去获取一个名为protoc-gen-go的插件,-u参数表示让命令通过网络来动态地更新已有的包及其依赖包,一般都要带这个参数,除此之外,goget命令还有一些其他参数,功能见表。参

数功

述-d只下载包而不安装-f忽略对已下载包导入路径的检查-fix在下载包后先进行修正,然后再编译和安装-insecure允许使用非安全通道(如HTTP而非HTTPS)去下载包-t同时下载并安装指定包测试文件中的依赖包安装第三方包2.编译安装有时候,所需的第三方包没有现成的可安装版本,可先下载其源代码,然后再编译安装。1)下载源代码下载源代码需要借助与远程包相匹配的代码管理工具,如Git、SVN、HG等,下面以Git为例介绍基本的操作方法。(1)安装Git访问/downloads,下载Git,得到可执行文件Git-2.41.0-64-bit.exe,双击启动安装向导,如图。安装第三方包(2)启动GitBash安装Git后可在开始菜单左上的“最近添加”中看到3个启动图标,如图。安装第三方包其中,第3个“GitBash”是Git配套的控制台,下载源代码的命令就通过它来执行,双击启动控制台,出现窗口如图5.8所示,在“$”提示符后输入命令。安装第三方包(3)克隆下载使用gitclone命令以“克隆”方式下载源代码,该命令可以复制远程仓库的所有代码和历史记录,并在本地创建一个与远程仓库完全相同的仓库的副本。通常将远程仓库中包(及其依赖组件)的源码克隆到本地的$GOPATH\src目录下,命令格式为:gitclonehttps://远程仓库路径/文件名.git$GOPATH/src/本地路径其中,“本地路径”是下载到本地的包的源代码存放路径,不一定要与远程仓库路径相同。例如:gitclone/grpc/grpc-go.git$GOPATH/src//grpc将Github远程仓库中grpc-go包的源代码下载到本地$GOPATH\src目录中的\grpc路径下,Git会自动创建存放源码路径上的各级文件夹目录。2)编译安装有了源代码,就可以将其编译成可运行的包并安装到Go环境中,使用goinstall命令进行编译安装。首先由GitBash控制台进入到$GOPATH\src目录,执行命令:cd$GOPATH/src/然后执行goinstall命令,格式为:goinstall本地路径(即源代码存放路径)@latest最后加“@latest”是为了将安装的包与其在网络上能够找到的最新版本同步。02包的管理1.包管理概述2.gomodule工具包的管理1.包管理概述1)vendor机制在很长一段时间内,Go官方并没有第三方包管理的解决方案,直到Go1.5引入了vendor机制,才为Go外部包的管理提供了有限的支持。该机制是在当前包中引入一个vendor目录,将该包所依赖的外部包复制到这个目录下,编译器在查找所需的第三方包时,也优先在该目录下找,流程如下。(1)如果当前包下有vendor目录,先从其下查找第三方的包,若找到就使用;若没找到或者当前包下根本就没有vendor目录,继续第(2)步。(2)沿当前包目录向上逐级查找直到$GOPATH\src,其间只要发现一个vendor目录就去里面查找,使用找到的第一个符合要求的包。(3)到$GOPATH下查找。(4)最终去到$GOROOT下查找。包的管理2)版本管理如果第三方包更新了,新版本与旧版本又不兼容怎么办?广大Go程序员迫切需要对第三方包进行更精细的管理,尤其对包的版本做精确的管控。起初,在Go社区出现了很多包管理工具,如godep、govendor、glide等,但是由于不同管理工具采用的是不同的元信息格式(如godep用Godeps.json、glide用glide.yaml),不利于社区发展,也严重违背了Go语言所追求的开箱即用、简单快速的设计理念。为了避免语言和工具的分裂,维护Go的设计理念,官方先是提供了一个叫作dep的工具,但并未马上集成到Go工具链,Go核心团队通过它来吸取实际使用经验并收集社区的反馈,不断实验、探索如何有效管理包版本,在此基础上终于开发出一个统一、强大的包管理工具gomodule,并于2019年9月3日发布的Go1.13中开始正式支持。包的管理2.gomodule工具gomodule以“模块(Module)”为基本单元来管理包,一个任意名称的目录(包括空目录)都可以作为模块,只要其中包含go.mod文件。通常开发中将项目整体作为一个模块,程序中引用包都是基于当前模块(项目)的相对路径,简化了编程。使用gomodule管理一个项目包的步骤如下。(1)将Go的环境变量GO111MODULE设置为on,开启gomodule功能。(2)创建模块通过以下命令创建一个新的模块:gomodinit模块名创建后会在当前包目录下生成一个go.mod文件,内容为:module模块名go1.xx包的管理(3)管理第三方包有了go.mod文件后,项目开发过程中gomodule就会自动地为用户进行包管理,如果用户想在项目中引入一个第三方包,比如要使用当前流行的Go-kit框架(用于微服务开发),就可以在go.mod文件中添加一句:require/go-kit/kitv0.12.0用require关键字引入该框架的0.12.0版本,然后就可以通过执行以下命令来手动下载这个框架及其依赖的所有第三方包:gomoddownload用户可以通过执行gomodvendor命令生成vendor目录,在其中集中放置go.mod文件描述的所有第三方包,还可以使用gomodtidy命令更新依赖关系,拉取缺少的包和移除不用的包。包的管理【实例5.3】将【实例5.2】的项目纳入gomodule管理。操作步骤如下。(1)在本地计算机的任一位置(如笔者是在C:\Users\Administrator)新建一个文件夹,其中创建项目目录MyBmi。(2)以管理员身份打开Windows命令行,执行如下命令打开gomodule功能:goenv-wGO111MODULE=on可运行goenv命令查看是否开启成功,如图。包的管理(3)将【实例5.2】项目MyBmi中的bmi包目录(内含human.go)及主程序main.go一起复制到本例项目目录MyBmi中,然后通过命令行进入其中执行创建模块的命令:cdC:\Users\Administrator\\MyBmigomodinitMyBmi过程如图。包的管理命令执行后在MyBmi目录中可见已经生成了go.mod文件,如图。用Windows记事本打开go.mod文件,可见其内容如下:moduleMyBmigo1.20这表示gomodule已将MyBmi项目视为一个模块加以管理了。包的管理(4)启动GoLand,选择“File”→“Open...”,弹出“OpenFileorProject”对话框,展开目录树进入到C:\Users\Administrator下的文件夹,选中MyBmi目录,单击“OK”按钮,如图,可在GoLand集成开发环境中打开此项目。包的管理(5)打开main.go,将导入bmi包的路径由全路径改为模块相对路径,如下:packagemainimport( "MyBmi/bmi" //用模块相对路径引用包 "fmt")funcmain(){ ...//主程序代码,略。}(6)用GoLand运行main.go,结果如图。包的管理事实上,GoLand就是通过gomodule工具来管理其Go项目的,在用户创建项目的时候就会自动在所建的项目目录中生成go.mod文件,大家可以打开之前用GoLand创建的项目自己去看一下,也只有包含go.mod文件的目录才会被GoLand识别为是一个Go项目,故本例若没有事先用gomodinit命令生成go.mod文件,而试图直接用GoLand打开项目目录就会出现如图所示的错误。第5章

源代码组织与管理Go语言与C语言Go语言与C语言在Go语言工具包中有一个Cgo命令,专用来处理Go调用C相关的操作,用户可以直接使用该命令,也可以在运行或构建Go程序时自动调用它。Cgo对于C代码的处理要依赖系统中C语言相关的编译工具,如gcc,在Go环境变量中默认已开启了对Cgo的支持,如图。Go语言与C语言【实例5.4】用Go语言调用C代码实现圆面积和周长的计算。(1)编写C代码在GoLand的默认项目awesomeProject目录下用Windows记事本创建一个C语言源文件circle.c,代码如下:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论