原文:How to Write Go Code

一些基本概念

  1. 下载 & 安装:golang.org/doc/install
  2. go tool:安装好 Go 之后自带的 cmd 工具,用于 fetch, build and install Go packages.
  3. workspace:每一个 Go 的项目代码都存储在一个 workspace 里
  4. 一个 workspace 可能包含多个版本管理的 repository(后面用 repo 简写)
  5. 每一个 repo 里可能包含一个或多个 packages
  6. 每一个 package 在一个文件夹里包含一个或多个 Go 源码文件
  7. 一个 package 的文件夹路径就是它的 import path

go tool 对代码的组织结构有特定的要求

Workspaces

Def: 一个 workspace 是一个有特定文件结构 hierarchy 的文件夹,其中根目录下有两个文件夹:

  • src:包含 Go 源代码
  • bin:包含可执行命令

go tool 会构建(build)和安装(install)可执行代码(binaries)到 bin 文件夹中。src 文件夹下的子文件夹即会包含多个 repo。

For Example:

bin/hello                          # command executableoutyet                         # command executable
src/github.com/golang/example/.git/                      # Git repository metadatahello/hello.go               # command sourceoutyet/main.go                # command sourcemain_test.go           # test sourcestringutil/reverse.go             # package sourcereverse_test.go        # test sourcegolang.org/x/image/.git/                      # Git repository metadatabmp/reader.go              # package sourcewriter.go              # package source... (many more repositories and packages omitted) ...
复制代码

GOPATH 环境变量

DefGOPATH 环境变量指向了你的 workspace 的位置。它在 Unix 的默认值是在你 Home 文件夹下的 $HOME/go 或是 Windows 里的 %USERPROFILE%\go(通常是 C:\Users\YourName\go)。

如果你希望设置多个不同的位置,可以通过设置 GOPATH 来解决。

GOPATH 不能与安装 Go 的位置一样

可以通过 go env GOPATH 看到目前的 GOPATH

开放 workspace's 里的 bin 子目录到 PATH(就是在 $GOPATH/bin/ 下的 cmd 可以直接调用了):

$ export PATH=$PATH:$(go env GOPATH)/bin
复制代码

设置 $GOPATH 到环境变量:

$ export GOPATH = $(go env GOPATH)
复制代码

Import paths

Def: 一个 import path 是代表一个 package 的唯一指代字段(String)。一个 package 的 import path 代表了其在一个 workspace 中的具体位置(也可能是一个远程 repo)。

  • Standard library 中的 packages:可以用 short import paths 来引入,如:"fmt""net/http"
  • 自己项目中的 packges:必须选择一个 base path 且避免与潜在其他 package、标准库 package、外部 package 有名字冲突。
  • 远程 repo:使用远程 repo 的根地址为 base path。如:一个 GitHub 的用户名 github.com/user 作为 base path

在我们自己的电脑上,我们可以先设置一个 base path(注意,这里 user 你可以自己随便写):

$ mkdir -p $GOPATH/src/github.com/user
复制代码

第一个 Program

我们来开发第一个项目,我们假设这个 package path 是 github.com/user/hello 并建立一个子文件夹作为 package 的文件夹:

$ mkdir $GOPATH/src/github.com/user/hello
复制代码

下一步则是建立一个文件 hello.go 作为源代码:

package mainimport "fmt"func main() {fmt.Println("Hello, world.")
}
复制代码

下一步就是用 go tool 来 build 和 install 这段代码:

$ go install github.com/user/hello
复制代码

这个命令会触发:

  1. 找到 package 的位置:
  • go tool 首先会通过 base path + package name 找到 workspace 里(因为 GOPATH 环境变量已经设置了 workspace 的位置)相应的 package path github.com/user/hello
  • 如果你当前的文件夹在 package path 中,即 $ cd $GOPATH/src/github.com/user/hello,那么就可以直接输入 $ go install 即可
  1. 构建 hello 命令,并生成一个可执行的 binary 文件
  2. 安装这个 binary 文件到 workspace 的 bin 文件夹下并命名为 hello,即 $GOPATH/bin/hello
  • 如果你上面已经通过把 $GOPATH/bin 加入到 $PATH 环境变量里,那么 hello 已经可以作为命令使用。

也就是如下效果:

$ $GOPATH/bin/hello
Hello, world.
复制代码

$ hello
Hello, world.
复制代码

第一个 Library

同样,像是建立一个 Program 一样,我们建立一个 Library 文件夹 stringutil

$ mkdir $GOPATH/src/github.com/user/stringutil
复制代码

然后在 stringutil 文件夹里建立一个文件 reverse.go

// Package stringutil contains utility functions for working with strings.
package stringutil// Reverse returns its argument string reversed rune-wise left to right.
func Reverse(s string) string {r := []rune(s)for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {r[i], r[j] = r[j], r[i]}return string(r)
}
复制代码

也如同上面所说,我们来构建(build)它,逐一这里我们只 build 不 install 因为这是一个 Library:

$ go build github.com/user/stringutil
复制代码

构建好后,如果我们想在我们的 Program 中引用这个 stringutil Library 则通过更新 GOPATH/src/github.com/user/hello 中的 hello.go 文件:

package mainimport ("fmt""github.com/user/stringutil"
)func main() {fmt.Println(stringutil.Reverse("!oG ,olleH"))
}
复制代码

下一步,我们重新 install hello

$ go install github.com/user/hello
复制代码

那么相应的 cmd hello 通过引用 stringutil Library 也有了新的输出:

$ hello
Hello, Go!
复制代码

这时,如果我们看 workspace 中的变化和文件结构就是:

bin/hello                 # command executable
src/github.com/user/hello/hello.go      # command sourcestringutil/reverse.go    # package source
复制代码

其中:

  • bin/hello 是 install 之后的可执行 binary 程序
  • github.com/user/hellohello Program
  • github.com/user/stringutilstringutil Library

Package names

每一个 Go 源代码文件的第一行必须是:

package name
复制代码

而这里 name 是 package 被引用时的默认名。在 Go 语言的常规使用中,import path 的最后一个元素即为 package name,例如:package 通过 "crypto/rot13" 引用,那么这个 package 的名字应该是 rot13

可运行的 cmd(也就是要被 install)的 binary 名必须是 main。而 package name 并不一定要不重复,只要 import paths 唯一即可。也就是 "util1/util""util2/util" 是不同的。

Testing

此处内容精炼,这里不做阐述了。

Remote packages 远程 packages

一个 import path 可以用来获取一个远程的 package(如 Git 或 Mercurial),go tool 会自动下载远程的 repo。例如,Go 官方的示例代码被存储在 GitHub 上,地址为 github.com/golang/example,使用 go get 命令即可自动 fetch, build and install,go get 会将 package 自动下载到 $GOPATH 中的第一个 workspace 中:

$ go get github.com/golang/example/hello
$ $GOPATH/bin/hello
Hello, Go examples!
复制代码

这个时候的 workspace 文件夹结构变成了:

bin/hello                           # command executable
src/github.com/golang/example/.git/                       # Git repository metadatahello/hello.go                # command sourcestringutil/reverse.go              # package sourcereverse_test.go         # test sourcegithub.com/user/hello/hello.go                # command sourcestringutil/reverse.go              # package sourcereverse_test.go         # test source
复制代码

这个时候,你可能会疑虑,就是 hello 之前是由 github.com/user/hello来定义的,而现在被 github.com/golang/example/hello 覆盖。

NEXT

  1. Effective Go 学习如何写出规范的 Go 代码: golang.org/doc/effecti…
  2. A Tour of Go 学习语言: tour.golang.org/
  3. 官方文档:golang.org/doc/

References:

  1. Go Website: golang.org/
  2. How to Write Go Code: golang.org/doc/code.ht…
  3. Set GOPATH: golang.org/wiki/Settin…

转载于:https://juejin.im/post/5d2fe95de51d451061721186

[译] 通过官网 Go 语言学习笔记 | How to Write Go Code相关推荐

  1. Docker学习笔记 [声明:基于官网教程的学习笔记]

    前言 对于我博客近来一直没有更新的原因,从2020年11月左右吧,开始忙着找工作的事情,11月底左右,学校举办了2021届校招,来学校的校招企业其实没几个比较好的(根据上一届学长得知,有的企业是培训机 ...

  2. 【Go语言 · 学习笔记】

    文章目录 Go语言 · 学习笔记 一.Go包管理 1. 什么是Go语言中的包 2. 包的命名 3. main包 4. 导入包 5. 远程包导入 6. 命名导入 7. 包的init函数 二.Go开发工具 ...

  3. R语言学习笔记——入门篇:第一章-R语言介绍

    R语言 R语言学习笔记--入门篇:第一章-R语言介绍 文章目录 R语言 一.R语言简介 1.1.R语言的应用方向 1.2.R语言的特点 二.R软件的安装 2.1.Windows/Mac 2.2.Lin ...

  4. Go语言学习笔记(二十)

    Go语言学习笔记(二十) 一.处理JSON 1 JSON简介 2 使用JSON API 3 在Go语言中使用JSON 4 解码JSON 5 映射数据类型 6 处理通过HTTP收到的JSON 7 相关问 ...

  5. Ink脚本语言学习笔记(四)

    目前想要基于Ink脚本语言和Unity新的UIToolkit做一套对话系统,本文对Ink脚本语言的使用方式做一下介绍和总结 Ink脚本语言学习笔记(三) 四.进阶故事流控制(Advanced Flow ...

  6. r语言c函数怎么用,R语言学习笔记——C#中如何使用R语言setwd()函数

    在R语言编译器中,设置当前工作文件夹可以用setwd()函数. > setwd("e://桌面//") > setwd("e:\桌面\") > ...

  7. 嵌入式C语言——学习笔记

    嵌入式C语言--学习笔记 计算机程序语言的学习思路? GCC的使用及其常用选项介绍 gcc概述 C语言编译过程 C语言常见的错误 预处理的使用 宏展开下的 #.## C语言常用关键字及运算符操作 关键 ...

  8. 梓益C语言学习笔记之链表&动态内存&文件

    梓益C语言学习笔记之链表&动态内存&文件 一.定义: 链表是一种物理存储上非连续,通过指针链接次序,实现的一种线性存储结构. 二.特点: 链表由一系列节点(链表中每一个元素称为节点)组 ...

  9. 6.方法(go语言学习笔记)

    6.方法(go语言学习笔记) 目录 定义 匿名字段 方法集 表达式 1. 定义 方法是与对象实例绑定的特殊函数. 方法是面向对象编程的基本概念,用于维护和展示对象的自身状态.对象是内敛的,每个实例对象 ...

最新文章

  1. 自然语言处理(NLP)之依存句法分析的可视化及图分析
  2. Documentum常见问题4—如何通过vlink方式直接查看文档内容
  3. 学习C++怎么进阶?
  4. 谈谈感想,8元体会易生信培训
  5. STM32工作笔记0096---用sprintf分配内存
  6. python高阶函数——sorted排序算法
  7. AutoMapper,对象映射的简单使用
  8. Python:如何安装与使用 pip
  9. MessageFormat用法
  10. OpenShift免费空间绑定顶级域名(图文教程)
  11. java二进制文件转xml_简单Java类与XML之间的转换
  12. 简述RUP软件过程模型的特点
  13. 厚物科技PXIe机箱PXI机箱PXIe便携机HW-1693BAT
  14. 拔丝芋头的Java学习日记---Day8
  15. 苏州计算机岗前培训,不忘初心 牢记使命——苏州五院2019年新职工岗前培训圆满完成...
  16. xlsx文件的多表读取与写入
  17. PostgreSQL-Docker创建PostgreSQL数据库并导入矢量数据
  18. 【Node.js】nvm的常用操作
  19. 百度App Android启动性能优化-工具篇
  20. JVM系列之JDK、JRE、JVM的区别是什么?(二)

热门文章

  1. 【Luogu1182】数列分段Section II(二分)
  2. matlab中memory模块初始值,Matlab的memory模块消除代数环
  3. 摇号系统怎么做_雨水收集系统怎么做
  4. git版本回退(3)
  5. 如何在CSDN上发gif - 超简单版本
  6. JAVA集合四:比较器--类自定义排序
  7. C/C++编程(尾积相乘)
  8. bzoj 3373: [Usaco2004 Mar]Lying Livestock 说谎的牲畜
  9. bzoj 1617: [Usaco2008 Mar]River Crossing渡河问题(DP)
  10. python 中 * 的使用和表示含义