《Go in Action》第三章读书笔记

本文为《Go in Action》的第三章读书笔记。
第二章主要是介绍package和工具相关的事情。

package

翻译一下就是包

Q: 什么是package?有什么用?

A: 原文:

All Go programs are organized into groups of files called packages, so that code has the ability to be included into other projects as smaller reusable pieces.

package就是a group of file。也就是一组文件。其作用就是package作为一个可重用的代码片段,被其他项目所使用。

Q: package如何定义?

A: 几点:

  • 每个文件的第一行使用pakage <name>定义package。这里的第一行指的是除了空行和注释的第一行。也就是说package那一行的上面还可以有注释或者空行,但是不能有其他代码。
  • 同一个文件夹下面不能有多个package。
  • 同一个package不能跨多个文件夹。
  • 一个文件夹下面的所有文件必须属于同一个package。
  • 通用做法是:文件夹的名字就是package的名字
  • package的名字应当是简洁的小写字母
  • 在代码中调用pacakge里面的东西时,默认使用pakage的名字,不过也可以覆盖。当你引入多个package,其名字是一样的时候,就需要覆盖了。

Q: package main特殊性?

A: 如下:

  • 告诉go的命令,需要将文件编译成为可执行文件
  • package main里面必须要有main函数

Q: go的hello world怎么写?

A: 如下:

  • 首先在$GOPATH/src目录下,建立hello文件夹
  • 创建hello.go文件
  • 写入如下内容:
package main

import "fmt"

func main() {
  fmt.Println("Hello World!")
}
  • 在hello文件夹下运行go build,会生成一个hello的可执行文件
  • 运行该可执行文件,输出Hello World

Q: pacakge如何引入?

A: 简单来说,就是使用import "<path/name>"这个语法。
单行:

import "fmt"

多行:

import (
  "fmt"
  "strings"
)

如下:

  • import寻找的路径是go环境使用目录的相对路径
  • 标准库里面的import路径是在go的安装路径下,比如可能是/usr/local/go
  • 其余的库的import路径是在GOPATH下
  • 首先会从go的安装路径下去找

两个特殊点的import:
显示声明名字:

import (
  fmt
  myfmt from "mylib/fmt"
} 

使用下划线(称为blank identifier):

import (
  fmt
  _ from "mylib/nothing"
)

remote imports

当import的内容是比如“github.com/spf13/viper”的时候,可以使用go get命令获取远程包到对应的目录下,以让本地可以用。
go get还是recursive的,即可以下载包及其依赖。

init函数

原文:

Each package has the ability to provide as many init functions as necessary to be invoked at the beginning of execution time. All the init functions that are discovered by the compiler are scheduled to be executed prior to the main function being executed.
When a program imports this package, the init function will be called

每个包可以有多个init函数(没明白...)。每个init函数都会在main函数被调用前执行。具体执行时间是在包被import的时候。

使用go tools

go的几个命名:

go #打印g的帮助信息
go build hello.go  #编译hello.go,生成可执行文件
go clean hello.go  #清理生成的文件
go build github.com/goinaction/code/chapter3/wordcount
go build github.com/goinaction/code/chapter3/...

go build wordcount.go 
go build .

go run wordcount.go

go vet main.go #检查代码错误
go format main.go

go doc tar
godoc -http=:6060 #

给package加注释,注释会展示在go doc中:

/*

Package usb provides types and functions for working with USB devices. To connect to a USB device start by creating a new USB connection with NewConnection ...

*/ 
package usb

分享代码

几条:

  • 代码可以上传到github,在github的repository的根目录直接创建package。不要建什么code或者src,这样import的时候路径会比较长
  • package可以是很小的,实现简单的功能,只有些许代码
  • 使用go fmt格式化代码
  • 给代码加注释

依赖管理

简单来说就是管理go的依赖包

什么是可重复制作(reproducible)?

简单来说,就是在我的电脑上编写的代码,在你的电脑上依然是同样的东西。为什么不一样呢?比如我们的代码存放位置不同,引用的import路径不同,引用的库的版本不同等。

vendoring

原文:

Community tools such as godep and vendor have solved the dependency problem by using a technique called vendoring and import path rewriting. The idea is to copy all the dependencies into a directory inside the project repo, and then rewrite any import paths that reference those dependencies by providing the location inside the project itself.

简单翻译:社区的一些如godep和vendor的工具在解决依赖问题的时候,使用了一种称为vendoring和重写import路径的技术。大意为将所有的依赖拷贝到项目中的一个目录下,然后重写所有的import路径,指向项目内部的那些拷贝过来的包。

这样项目使用到的所有代码都在项目目录下了,直接zip一下就包含了源文件和引用到的其他库文件了。

在vendor前:

package main

import (
  "bitbucket.org/ww/goautoneg"
  "github.com/beorn7/perks"
)

vendor之后:

package main

import (
"github.ardanstudios.com/myproject/Godeps/_workspace/src/ bitbucket.org/ww/goautoneg"
"github.ardanstudios.com/myproject/Godeps/_workspace/src/ github.com/beorn7/perks"
)

gb

原文:

Gb is a whole new class of build tool being developed by members of the Go community. Gb takes a different approach to solving the reproducible-build problem, which starts with the understanding that wrapping the Go tooling is not an option.

gb代表了一类新的构建工具,其表示对go tooling进行又一层封装,并不是解决reproducible问题的一种可选项。

The philosophy behind gb stems from the idea that Go doesn’t have reproducible builds because of the import statement. The import statement drives go get, but import doesn’t contain sufficient information to identify which revision of a package should be fetched any time go get is called. The possibility that go get can fetch a different version of code for any given package at any time makes supporting the Go tooling in any reproducible solution complicated and tedious at best.

gb认为go无法保证reproducible builds的原因在于import。因为go get从import获取信息,但是import并没有表示包版本的信息,所以go get也不知道获取哪个特定版本的库,很有可能获取了一个不同版本的依赖库。

A gb project is simply a directory on disk that contains a subdirectory named src/. The symbol $PROJECT refers to the root directory on disk where the src/ directory is located and is only used as a shortcut for describing the location on disk for the project.

一个gb的项目简单来说就是一个具有src子目录的目录,也就是一个目录下面有一个叫src的子目录。$PROJECT指向了该目录的路径。

Gb projects differentiate between the code you write and the code your code depends on. The code your code depends on is called vendored code. A gb project makes a clear distinction between your code and vendored code.

Gb规定用户编写的代码叫code,其依赖的代码叫vendored code。其存放路径为:

$PROJECT/src
$PROJECT/vendor/src

gb不需要改动源码里面的import的路径。

The gb tool will look inside the PROJECT/vendor/src/ directory for these imports if they can’t be located inside thePROJECT/src/ directory first. The entire source code for the project is located within a single repo and directory on disk, split between the src/ and vendor/src/ subdirectories.

gb工具会去PROJECT/vendor/src去寻找import的库。所有的代码都放在了PROJECT目录下。

这些目录结构的约定都是gb自己定的,go工具不认识,因此不能使用go工具,需要使用gb这个工具。比如编译一个项目:

gb build all
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容