go list 命令的作用是列出指定的 代码包 的信息。与其他命令相同,我们需要以 代码包导入路径 的方式给定代码包。被给定的代码包可以有多个。这些代码包对应的目录中必须直接保存有 Go 语言源码文件,其子目录中的文件不算在内。否则,代码包将被看做是不完整的。现在我们来试用一下:

hc@ubt:~$ go list cnet/ctcp pkgtool
cnet/ctcp
pkgtool

我们看到,在不加任何标记的情况下,命令的结果信息中只包含了我们指定的代码包的导入路径。我们刚刚提到,作为参数的代码包必须是完整的代码包。例如:

hc@ubt:~$ go list cnet pkgtool
can't load package: package cnet: no buildable Go source files in /home/hc/golang/goc2p/src/cnet/
pkgtool

这时,go list 命令报告了一个错误——代码包 cnet 对应的目录下没有 Go 源码文件。但是命令还是把代码包 pkgtool 的导入路径打印出来了。然而,当我们在执行 go list 命令并加入标记 -e 时,即使参数中包含有不完整的代码包,命令也不会提示错误。示例如下:

hc@ubt:~$ go list -e cnet pkgtool
cnet
pkgtool

标记 -e 的作用是以容错模式加载和分析指定的代码包。在这种情况下,命令程序如果在加载或分析的过程中遇到错误只会在内部记录一下,而不会直接把错误信息打印出来。我们为了看到错误信息可以使用 -json  标记。这个标记的作用是把代码包的结构体实例用 JSON 的样式打印出来。

这里解释一下,JSON 的全称是 Javascript Object Notation。它一种轻量级的承载数据的格式。JSON 的优势在于语法简单、短小精悍,且非常易于处理。JSON 还是一种纯文本格式,独立于编程语言。正因为如此,得到了绝大多数编程语言和浏览器的支持,应用非常广泛。Go 语言当然也不例外,在它的标准库中有专门用于处理和转换 JSON 格式的数据的代码包 encoding/json。关于 JSON 格式的具体内容,读者可以去它的 官方网站 查看说明。

在了解了这些基本概念之后,我们来试用一下 -json 标记。示例如下:

hc@ubt:~$ go list -e -json cnet
{
"Dir": "/home/hc/golang/goc2p/src/cnet",
"ImportPath": "cnet",
"Stale": true,
"Root": "/home/hc/golang/goc2p",
"Incomplete": true,
"Error": {
"ImportStack": [
"cnet"
],
"Pos": "",
"Err": "no Go source files in /home/hc/golang/goc2p/src/cnet"
}
}

在上述 JSON 格式的代码包信息中,对于结构体中的字段的显示是不完整的。因为命令程序认为我们指定 cnet 就是不完整的。在名为 Error 的字段中,我们可以看到具体说明。Error 字段的内容其实也是一个结构体。在 JSON 格式下,这种嵌套的结构体被完美的展现了出来。Error 字段所指代的结构体实例的 Err 字段说明了 cnet 不完整的原因。这与我们在没有使用 -e 标记的情况下所打印出来的错误提示信息是一致的。我们再来看 Incomplete 字段。它的值为 true 。这同样说明 cnet 是一个不完整的代码包。

实际上,在从这个代码包结构体实例到 JSON 格式文本的转换过程中,所有的值为其类型的空值的字段都已经被忽略了。

现在我们使用带 -json 标记的 go list 命令列出代码包 cnet/ctcp 的信息:

hc@ubt:~$ go list -json cnet/ctcp
{
"Dir": "/home/hc/golang/github/goc2p/src/cnet/ctcp",
"ImportPath": "cnet/ctcp",
"Name": "ctcp",
"Target": "/home/hc/golang/github/goc2p/pkg/darwin_amd64/cnet/ctcp.a",
"Stale": true,
"Root": "/home/hc/golang/github/goc2p",
"GoFiles": [
"base.go",
"tcp.go"
],
"Imports": [
"bufio",
"bytes",
"errors",
"logging",
"net",
"sync",
"time"
],
"Deps": [
"bufio",
"bytes",
"errors",
"fmt",
"internal/singleflight",
"io",
"log",
"logging",
"math",
"math/rand",
"net",
"os",
"reflect",
"runtime",
"runtime/cgo",
"sort",
"strconv",
"strings",
"sync",
"sync/atomic",
"syscall",
"time",
"unicode",
"unicode/utf8",
"unsafe"
],
"TestGoFiles": [
"tcp_test.go"
],
"TestImports": [
"bytes",
"fmt",
"net",
"runtime",
"strings",
"sync",
"testing",
"time"
]
}

由于 cnet/ctcp 包是一个完整有效的代码包,所以我们不使用 -e 标记也是没有问题的。在上面打印的 cnet/ctcp 包的信息中没有 Incomplete 字段。这是因为完整的代码包中的 Incomplete 字段的其类型的空值 false。它已经在转换过程中被忽略掉了。另外,在 cnet/ctcp 包的信息中我们看到了很多其它的字段。现在我就来看看在 Go 命令程序中的代码包结构体都有哪些公开的字段。如下表。

表0-7 代码包结构体中的基本字段

字段名称 字段类型 字段描述
Dir 字符串(string) 代码包对应的目录。
ImportPath 字符串(string) 代码包的导入路径。
ImportComment 字符串(string) 代码包声明语句右边的用于自定义导入路径的注释。
Name 字符串(string) 代码包的名称。
Doc 字符串(string) 代码包的文档字符串。
Target 字符串(string) 代码包的安装路径。
Shlib 字符串(string) 包含该代码包的共享库(shared library)的名称。
Goroot 布尔(bool) 该代码包是否在Go语言安装目录下。
Standard 布尔(bool) 该代码包是否属于标准库的一部分。
Stale 布尔(bool) 该代码包的最新代码是否未被安装。
Root 字符串(string) 该代码包所属的工作区或Go安装目录的路径。

表0-8 代码包结构体中与源码文件有关的字段

字段名称 字段类型 字段描述
GoFiles 字符串切片([]string) Go 源码文件的列表。不包含导入了代码包“C”的源码文件和测试源码文件。
CgoFiles 字符串切片([]string) 导入了代码包“C”的源码文件的列表。
IgnoredGoFiles 字符串切片([]string) 忽略编译的源码文件的列表。
CFiles 字符串切片([]string) 名称中有“.c”后缀的源码文件的列表。
CXXFiles 字符串切片([]string) 名称中有“.cc”、“.cxx”或“.cpp”后缀的源码文件的列表。
MFiles 字符串切片([]string) 名称中“.m”后缀的源码文件的列表。
HFiles 字符串切片([]string) 名称中有“.h”后缀的源码文件的列表。
SFiles 字符串切片([]string) 名称中有“.s”后缀的源码文件的列表。
SwigFiles 字符串切片([]string) 名称中有“.swig”后缀的文件的列表。
SwigCXXFiles 字符串切片([]string) 名称中有“.swigcxx”后缀的文件的列表。
SysoFiles 字符串切片([]string) 名称中有“.syso”后缀的文件的列表。这些文件是需要被加入到归档文件中的。

表0-9 代码包结构体中与 Cgo 指令有关的字段

字段名称 字段类型 字段描述
CgoCFLAGS 字符串切片([]string) 需要传递给C编译器的标记的列表。针对Cgo。
CgoCPPFLAGS 字符串切片([]string) 需要传递给C预处理器的标记的列表。针对Cgo。
CgoCXXFLAGS 字符串切片([]string) 需要传递给C++编译器的标记的列表。针对Cgo。
CgoLDFLAGS 字符串切片([]string) 需要传递给链接器的标记的列表。针对Cgo。
CgoPkgConfig 字符串切片([]string) pkg-config的名称的列表。针对Cgo。

表0-10 代码包结构体中与依赖信息有关的字段

字段名称 字段类型 字段描述
Imports 字符串切片([]string) 该代码包中的源码文件显式导入的依赖包的导入路径的列表。
Deps 字符串切片([]string) 所有的依赖包(包括间接依赖)的导入路径的列表。

表0-11 代码包结构体中与错误信息有关的字段

字段名称 字段类型 字段描述
Incomplete 布尔(bool) 代码包是否是完整的,也即在载入或分析代码包及其依赖包时是否有错误发生。
Error *PackageError类型 载入或分析代码包时发生的错误。
DepsErrors []*PackageError类型 载入或分析依赖包时发生的错误。

表0-12 代码包结构体中与测试源码文件有关的字段

字段名称 字段类型 字段描述
TestGoFiles 字符串切片([]string) 代码包中的测试源码文件的名称列表。
TestImports 字符串切片([]string) 代码包中的测试源码文件显示导入的依赖包的导入路径的列表。
XTestGoFiles 字符串切片([]string) 代码包中的外部测试源码文件的名称列表。
XTestImports 字符串切片([]string) 代码包中的外部测试源码文件显示导入的依赖包的导入路径的列表。

代码包结构体中定义的字段很多,但有些时候我们只需要查看其中的一些字段。那要怎么做呢 ? 标记 -f 可以满足这个需求。比如这样:

hc@ubt:~$ go list -f {{.ImportPath}} cnet/ctcp
cnet/ctcp

实际上,-f 标记的默认值就是 {{.ImportPath}} 。这也正是我们在使用不加任何标记的 go list 命令时依然能看到指定代码包的导入路径的原因了。

标记 -f 的值需要满足标准库的代码包 text/template 中定义的语法。比如,{{.S}} 代表根结构体的 S 字段的值。在 go list 命令的场景下,这个根结构体就是指定的代码包所对应的结构体。如果 S 字段的值也是一个结构体的话,那么 {{.S.F}} 就代表根结构体的 S 字段的值中的 F 字段的值。如果我们要查看 cnet/ctcp 包中的命令源码文件和库源码文件的列表,可以这样使用 -f 标记:

hc@ubt:~$ go list -f {{.GoFiles}} cnet/ctcp
[base.go tcp.go]

如果我们想查看不完整的代码包 cnet 的错误提示信息,还可以这样:

hc@ubt:~$ go list -e -f {{.Error.Err}} cnet
no buildable Go source files in /home/hc/golang/goc2p/src/cnet

我们还可以利用代码包 text/template 中定义的强大语法让 go list 命令输出定制化更高的代码包信息。比如:

hc@ubt:~$ go list -e -f 'The package {{.ImportPath}} is {{if .Incomplete}}incomplete!{{else}}complete.{{end}}' cnet
The package cnet is incomplete! ```bash
hc@ubt:~$ go list -f 'The imports of package {{.ImportPath}} is [{{join .Imports ", "}}].' cnet/ctcp
The imports of package cnet/ctcp is [bufio, bytes, errors, logging, net, sync, time].

其中,join 是命令程序在 text/template 包原有语法之上自定义的语法,在底层使用标准库代码包 strings 中的 Join 函数。关于更多的语法规则,请读者查看代码包 text/template 的相关文档。

另外,-tags 标记也可以被 go list 接受。它与我们在讲 go build 命令时提到的 -tags 标记是一致的。读者可以查看代码包 "go/build`` 的文档以了解细节。

go list 命令很有用。它可以为我们提供指定代码包的更深层次的信息。这些信息往往是我们无法从源码文件中直观看到的。

摘自:

http://wiki.jikexueyuan.com/project/go-command-tutorial/0.8.html

【Go命令教程】9. go list的更多相关文章

  1. Make 命令教程 -- 阮一峰

    摘自http://www.ruanyifeng.com/blog/2015/02/make.html Make 命令教程 作者: 阮一峰 日期: 2015年2月20日 代码变成可执行文件,叫做编译(c ...

  2. 痞子衡嵌入式:第一本Git命令教程(0)- 索引

    大家好,我是痞子衡,是正经搞技术的痞子.本系列痞子衡给大家讲的是Git命令汇编,共12篇文章,循序渐进地介绍Git操作的完整过程. 在开始Git课程之前,需要先跟大家普及2个重要概念(四度空间.四种状 ...

  3. Android ADB命令教程二——ADB命令详解

    Android ADB命令教程二——ADB命令详解 转载▼ 原文链接:http://www.tbk.ren/article/249.html       我们使用 adb -h 来看看,adb命令里面 ...

  4. 天河2号-保持使用yhrun/srun时连接不中断 (screen 命令教程 )

    问题重述: 当我们使用天河机进行并行程序实验的时候,都会使用到yhrun/srun命令.在超算环境下,yhrun 命令用来进行提交交互式作业,有屏幕输出.但是容易受到网络波动影响导致断网或者关闭窗口最 ...

  5. 【Go命令教程】命令汇总

    [Go命令教程]1. 标准命令详解 [Go命令教程]2. go build [Go命令教程]3. go install [Go命令教程]4. go get [Go命令教程]5. go clean [G ...

  6. Windows 批处理(cmd/bat)常用命令教程

    Windows批处理(cmd/bat)常用命令教程 简单详细,建议收藏 常见问题: 1.如果你自己编写的.bat文件,双击打开,出现闪退 2.批处理.bat 文件中输出中文乱码 解决方法在文章末尾! ...

  7. MySQL使用教程收集(语法教程/命令教程)

    说明:现在市面上的教程除了基本语法外,都基本是五花八门的,最权威且最全面的解释应该上官网去查看. https://www.tutorialspoint.com/mysql/index.htm http ...

  8. Make 命令教程

    http://www.ruanyifeng.com/blog/2015/02/make.html 作者: 阮一峰 日期: 2015年2月20日 代码变成可执行文件,叫做编译(compile):先编译这 ...

  9. npm命令教程

    教程:http://www.runoob.com/nodejs/nodejs-npm.html 常用命令:http://www.cnblogs.com/PeunZhang/p/5553574.html

  10. 痞子衡嵌入式:第一本Git命令教程(7.1)- 清理之缓存(stash)

    今天是Git系列课程第七课,上一课我们学会了查看Git本地历史提交,今天痞子衡要讲的是Git仓库的清理操作,一共4个命令,都是日常开发中非常实用的命令,掌握这4个命令,会让你有一种玩弄Git仓库于股掌 ...

随机推荐

  1. sqlserver2008R2数据库自动备份脚本

    CREATE proc [dbo].[usp_autoBackupDB] @dbname sysname=null --要备份的数据库名,不指定即为全部备份 ,)='d:\' --备份目录路径 ,)= ...

  2. Quartus II 安装教程—FPGA入门教程【钛白Logic】

    Quartus II 工具安装一般分为两个部分,首先是开发工具本身的安装,其次就是器件库的安装,我们可以根据我们的需要选择相应的器件库来安装,这里我们使用Cyclone IV的FPGA,即安装Cycl ...

  3. springcloud搭建服务注册中心与服务发现

    1.创建服务注册中心 创建一个普通的Spring Boot工程 首先我们需要创建一个普通的Spring Boot工程,命名为eureka-server,普通到什么程度呢?就是一个starter都不需要 ...

  4. Java基础87 MySQL数据约束

    1.默认值 -- 创建表student1,设置address字段有默认值 create table student1 ( id int, name ), address ) default '广东省深 ...

  5. 标签流 VS 脚本流

    搞过点前端,玩过几个框架之后,基本都会发现框架在设计上的一些套路和流派,今天给大家扒一扒其中的两个书写流派“标签流”和“脚本流” 我们以一个button按钮为例: 这样裸写HTML标签的方式基本没法儿 ...

  6. 关于idtcpserver的使用

    原文:http://blog.csdn.net/hnxxcxg/article/details/2798019 用idTCPServer,客户端接上来时,如何取得客户端的IP? IP:=AThread ...

  7. Docker 图形化页面管理工具使用

    一.Docker图形化工具 docker 图形页面管理工具常用的有三种,DockerUI ,Portainer ,Shipyard .DockerUI 是 Portainer 的前身,这三个工具通过d ...

  8. 【LOJ】#2532. 「CQOI2018」社交网络

    题解 基尔霍夫矩阵,外向树是入度矩阵-邻接矩阵 必须删掉第一行第一列然后再求行列式 代码 #include <bits/stdc++.h> #define fi first #define ...

  9. C++雾中风景10:聊聊左值,纯右值与将亡值

    C++11的版本在类型系统上下了很大的功夫,添加了诸如auto,decltype,move等新的关键词来简化代码的编写与降低阅读代码的难度.为了更好的理解这些新的语义,笔者确定通过几篇文章来简单窥探一 ...

  10. linux下mysql操作命令集合

    转载:http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/10/18/2216279.html 1.linux下启动mysql的命令:mysq ...