Go

Go Go Go

尴尬了,这篇的日期写的是2018-01-03,实际上是近三年前的帖子了。Go 1.9发布的时候就信誓旦旦的要进行学习。结果到今天还是无疾而终的样子,半途而废了好久。捞上来,看看这次可以坚持多久。

Mixin 大群部署完全教程 拿这个练习,前后端一起端。

week 26

重新更新了环境,使用go1.14.4开始,即使在window环境上,安装也只需要解压、更新环境变量(如果使用cgo的话,还需要gcc环境,机器上已经有了,但目前以我这水平应该还用不到)就可以立即上手了。

How to write Go code实践——

  • 创建工作目录,后续在工作目录进行操作
  • 使用go mod init example.com/user/hello进行初始化,生成go.mod文件,包含了包名和使用的版本名
  • 使用go install进行安装,三种等价操作。go install ., go install example.com/user/hello
  • 在本地定义引用的包信息:目录名作为引入的内容,其中的方法使用大写字母开头自动exported,使用go build就可以将引用包安装到本地。之后就可以在应用中使用
  • 引入remote的包会自动去下载远程的包。通过go installgo buildgo run都可以触发下载动作,并会更新go.mod文件
  • 使用 go test进行测试

注意事项:

  1. 可以使用go env -w GOBIN=/path/to/bingo env -u GOBIN进行变量声明和修改
  2. 在cmd环境下可以临时设置代理,持续到窗口关闭,前提是本地已经有了proxyset http_proxy=http://127.0.0.1:7890, set https_proxy=http://127.0.0.1:7890
  3. 使用go test ./...可以自动遍历当前工程所有文件夹下的test文件

要用到go module,参考这两篇——Go Modules 终极入门干货满满的 Go Modules 和 goproxy.cn

week 27

Gocker Docker

用 Go 从头实现一个迷你 Docker — Gocker
原文: Containers the hard way: Gocker: A mini Docker written in Go
源码:Gocker

这个看起来有点帅啊,而且代码不是很多的样子,结合耗子叔的这几篇一起理解更有帮助——

DOCKER基础技术:LINUX NAMESPACE(上)
DOCKER基础技术:LINUX NAMESPACE(下)
DOCKER基础技术:LINUX CGROUP
DOCKER基础技术:AUFS
DOCKER基础技术:DEVICEMAPPER

week 28

Go Echo: get started, Go Echo: basic features跟着这个例子写一个简单的登录demo。

趁热打铁,第三篇新鲜出炉Go Echo: custom Binder

  • param tag 对应路径参数;
  • query tag 对应 URL 参数;
  • json tag 对应 application/json 方式参数;
  • form tag 对应 POST 表单数据;
  • xml tag 对应 application/xml 或 text/xml;
// 表述结构体对应数据绑定时,对应的tag和字段。 如,json类型的name字段;form类型的name字段
type User struct {
 Name string `query:"name" form:"name" json:"name" xml:"name"`
 Sex  string `query:"sex" form:"sex" json:"sex" xml:"sex"`
}

顺带安装一下很好用的http调试工具httpie,python写得,依赖python3.6以上版本(本地的环境已经很混乱得啥都有, 使用py --version可以调用python3版本),直接使用 pip install --upgrade httpie安装成功了。

没有进行数据绑定时,传递xml类型数据时,被认为是Content-Type: text/plain;;指定了绑定规则后可以识别并转换为Content-Type: application/json; charset=UTF-8

go vendor 依赖

低版本下对于vendor目录的查找逻辑:

  • 需要将项目建立在$GOPATH目录下的src目录(前提)
  • 查找当前工程下的vendor目录(vendor tree) (如果项目没有在$GOPATH目录下,这一步将会被忽略)go issue #14566
  • $GOROOT目录下查找(from $GOROOT)
  • $GOPATH目录下查找(from $GOPATH)

archive

Go release 1.9 version on 24 August 2017. I’m the 31,365 people to start it on github and just get started to learn it :).

Go 1.9 is released. Here are all the blogs about go.

Go: Ten years and climbing Go十年 BIG: Blockchain In Go

VS环境设置:

Go tools that the Go extension depends on

Ctrl + b: 显示/隐藏侧边栏 Ctrl + j: 显示/隐藏Panel控制栏

update project

# Add Hugo and its package dependencies to your go src directory.
go get -v github.com/gohugoio/hugo

$GOPATH 目录约定有三个子目录:

  • src 存放源代码(比如:.go .c .h .s等)
  • pkg 编译后生成的文件(比如:.a)
  • bin 编译后生成的可执行文件(为了方便,可以把此目录加入到 $PATH 变量中,如果有多个gopath,那么使用${GOPATH//://bin:}/bin添加所有的bin目录)
$ go env
set GOARCH=amd64
set GOBIN=
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=F:\Tools\gopath\
set GORACE=
set GOROOT=F:\Tools\go
set GOTOOLDIR=F:\Tools\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=G:\TempFolder\userTemp\go-build565356171=/tmp/go-build -gno-record-gcc-switches
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config

go get golang.org/x 包失败解决方法

方案由于限制问题,国内使用 go get 安装 golang 官方包可能会失败

go get -v golang.org/x/tour/pic
Fetching https://golang.org/x/tour/pic?go-get=1
https fetch failed: Get https://golang.org/x/tour/pic?go-get=1: dial tcp 216.239.37.1:443: i/o timeout
package golang.org/x/tour/pic: unrecognized import path "golang.org/x/tour/pic" (https fetch: Get https://golang.org/x/tour/pic?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)

golang 在 github 上建立了一个镜像库,如 https://github.com/golang/net 即是 https://golang.org/x/net 的镜像库

获取 golang.org/x/net 包,其实只需要以下步骤:

mkdir -p $GOPATH/src/golang.org/x
cd $GOPATH/src/golang.org/x
git clone https://github.com/golang/net.git

## example
➜  src mkdir -p golang.org/x
➜  src cd golang.org/x
➜  x git clone https://github.com/golang/tour.git
Cloning into 'tour'...
remote: Counting objects: 2092, done.
remote: Total 2092 (delta 0), reused 0 (delta 0), pack-reused 2092
Receiving objects: 100% (2092/2092), 895.19 KiB | 133.00 KiB/s, done.
Resolving deltas: 100% (1329/1329), done.
## now you can import "golang.org/x/tour/pic" 

其它 golang.org/x 下的包获取皆可使用该方法

或者使用软连接的方式代替

git clone https://github.com/golang/net.git $GOPATH/src/github.com/golang/net

git clone https://github.com/golang/sys.git $GOPATH/src/github.com/golang/sys

git clone https://github.com/golang/tools.git $GOPATH/src/github.com/golang/tools

ln -s $GOPATH/src/github.com/golang $GOPATH/src/golang.org/x1

go test

同事的项目本地执行没有问题,线上跑go test的时候一直无法通过,build 失败。

最终定位原因:

  • 环境需要安装gcc环境
  • 打开golang的环境变量 CGO_ENABLED="1"

环境默认是打开了CGO的,但执行go test时会报gcc错误。为了不安装gcc环境,强制修改了这个变量(还尝试了半天修改的方法)

这是因为甚至是go test ./...时,有些报会使用到 “C混合编译”,需要注意这俩个关键因素。

go import

Understanding Dependency Management in Go Understanding Vendoring:

In order to be able to fully understand how vendoring works we must understand the algorithm used by Go to resolve import paths, which is the following:

  1. Look for the import at the local vendor directory (if any)
  2. If we can’t find this package in the local vendor directory we go up to the parent folder and try to find it in the vendor directory there (if any)
  3. We repeat step 2 until we reach $GOPATH/src
  4. We look for the imported package at $GOROOT
  5. If we can’t find this package at $GOROOT we look for it in our $GOPATH/src folder

go mod

Go mod 使用
告别GOPATH,快速使用 go mod(Golang包管理工具)

go.mod文件中定义了当前项目对应的module名称,如golang.gebitang.com/my/module

对于pkg/util/log的包,当前项目中使用import时,可以使用下面的方式进行引入。go mod模块会自动进行转换

import (
    "golang.gebitang.com/my/module/pkg/util/log"
)

go mod将依赖统一放到GOPATH下的pkg下的pkg下面,并且支持不同版本(使用@vMajor.minor.path)的格式管理

As you append to a slice, its capacity doubles in size every time it exceeds its current capacity.

 
comments powered by Disqus