Go 语言模块化编程 - go module ( 三 ) 简单的模块

yufei       6 年, 3 月 前       2638

在前两个章节 Go 语言模块化编程 - go module ( 一 )Go 语言模块化编程 - go module ( 二 ) 中,我们简单的介绍了一下 go module 的基础知识和会用到的工具链,本章节我们可以开始我们的第一个 go module 之旅了

建立实验环境

我们将使用最近发布的 go1.11beta2 来开启我们的 go module 实验之旅

安装 Go 1.11 的方法有很多种,我们可以打开官方的下载页面 https://golang.org/dl/ 一直拉到最底部,点开 「 Unstable version 」 就可以看到下载连接

  1. 如果你从未安装过,可以选择一个适合你的平台的版本,然后点击链接下载安装

    如果你不知道怎么安装,可以参考我们的 Golang 基础教程:Go 语言环境配置

  2. 如果你已经安装过,则可以通过下面的命令快速安装

    go get golang.org/dl/go1.11beta2
    

    注意:使用此方法安装的,因为 go1.11beta2 还不是正式稳定版,所有的命令都是 go1.11beta2 开头而非 go

安装完成后就可以使用 go versiongo1.11beta2 version 命令查看下当前的版本

$ go version
go version go1.11beta2 darwin/amd64

如果你感兴趣,可以使用 go help mod 命令查看下 go module 的手册

之前的开发模式 GOPATH mode

go module 出现之前,我们的开发一般是下面这种流程,假设我们当前的项目需要依赖 github/ijoywan/c

我们在 ~/go/a 目录下建立一个 hello 目录 ( 注意: $GOPATH = /Users/yufei/Developer/go,显然 hello 目录并不在 GOPATH 下面)。 ~/go/a/hello/ 目录下有一个 hello.go 文件,内容如下

~/go/a/hello/hello.go

package main

/*
 * hello.go
 */

import "github.com/ijoywan/c"

func main() {
    c.CallC()
}

保存,然后使用 go build hello.go 构建下 hello.go 这个源码文件,会输出如下错误

$ go build hello.go 
hello.go:7:8: cannot find package "github.com/ijoywan/c" in any of:
    /usr/local/go/src/github.com/ijoywan/c (from $GOROOT)
    /Users/yufei/Developer/go/src/github.com/ijoywan/c (from $GOPATH)

构建错误!错误原因很明了:在本地的 GOPATH 下并没有找到 github.com/ijoywan/c 路径的 package c 。传统 fix 这个问题的方法是手工将 package c 通过 go get 下载到本地 (并且 go get 会自动下载package c 所依赖的 package d )

$ go get github.com/ijoywan/c

完成后然后使用下面的命令就可以运行了

lie:hello luojianguo$ go get github.com/ijoywan/c
lie:hello luojianguo$ go run hello.go
call C: v1.0.0
   --> call D:
    Hello World! FROM Module D: v5.2.0
   --> call D end

这种我们最熟悉的 Go compiler 从 $GOPATH 下(以及 vendor 目录下)搜索目标程序的依赖包的模式称为:「 GOPATH mode 」

go module 开发模式 module-aware mode

Go module 的引入在 Go 1.8 版本上更进了一步,它引入了一种新的依赖模式 「 module-aware」

在该模式下,某源码树 ( 通常是一个 repo ) 的顶层目录下会放置一个 go.mod 文件,每个 go.mod 文件定义了一个 module ,而放置 go.mod 文件的目录被称为 module root 目录(通常对应一个 repo 的 root 目录,但不是必须的)

module root 目录以及其子目录下的所有 Go package 均归属于该 module,除了那些自身包含 go.mod 文件的子目录

在 「 module-aware 」模式下,go 编译器将不再在 GOPATH 下面以及 vendor 下面搜索目标程序依赖的第三方 Go packages

接下来我们改造下刚刚的项目,看一下在 「 module-aware 」 模式下的 hello.go 的构建过程

我们首先在 ~/go/a/hello/ 目录下创建一个 go.mod 文件,并输入以下内容

~/go/a/hello/go.mod

module hello

接着使用下面的命令重新运行 hello.go

$ go run hello.go
go: finding github.com/ijoywan/c latest
go: finding github.com/ijoywan/d v1.0.0
go: downloading github.com/ijoywan/d v1.0.0
call C: v1.0.0
   --> call D:
    Hello World! FROM Module D: v5.2.0
   --> call D end

可以看到在这种模式下,go 编译器并没有去使用之前就已经下载好的 GOPATH 目录下的 github.com/ijoywan/cgithub.com/ijoywan/d 。而是主动去下载这两个包并成功编译

接下来我们使用 cat go.mod 命令看看 go buildgo run 命令执行后的 go.mod 文件的内容

module hello

require github.com/ijoywan/c v0.0.0-20180803083505-aaafa13e3e67 // indirect

看到这个文件内容,你是否会疑问,为啥 github.com/ijoywan/d 没有包含进来

其实我也有疑问,但目前这个章节我还不想去追溯,因为这涉及到依赖和版本的问题

其实在改造的过程,我掉进了很多坑,尤其是版本号这个坑,如果你看我的 github.com 上的提交记录,就会知道这个坑有多大

本章节,我们就到此结束把,有关更多问题,我们会在接下来的章节中继续讲解

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.