golang 基础知识


原文链接: golang 基础知识

golang – 峰云就她了
Golang笔记
解决编程问题
Golang知识库
Cyeam
golanger/Golang学习笔记

代理实现(1) goproxy

https://golang.org/cmd/go/#hdr-Module_proxy_protocol
我推荐几个代理地址:
https://goproxy.io
https://gocenter.io
https://athens.azurefd.net/

export GOPROXY=https://goproxy.io
export GOPROXY=https://mod.gokit.info
export GOPROXY=https://mirrors.aliyun.com/goproxy/
export GOPROXY=https://goproxy.cn ## (这个有时不行)
export GOPROXY=https://proxy.golang.org

GOPROXY="https://proxy.golang.org,https://goproxy.io,direct"

First, you will need to enable the Go Modules feature and configure Go to use the proxy.
bash(Linux)
export GOPROXY=https://goproxy.io
PowrShell(Windows)
$env:GOPROXY = "https://goproxy.io"

Now, when you build and run your applications, go will fetch dependencies via goproxy.io.
用代理 GOPROXY=https://athens.azurefd.net。国内可用,
文档在 https://docs.gomods.io/

$env:GO111MODULE=on

代理实现(2) go-get直接使用 ss 的 socks5 代理

go get 下载软件包时遇到的翻墙问题确实很烦人。而且 git config 里面配的代理也是会导致go get失败的。
因为当你使用 go get golang.org/x/crypto 时,需要先访问 https://golang.org/x/crypto?go-get=1 来获取版本库的类型是 git 或 svn 或是其它 。这个阶段 git config 配置的代理是不起作用的。所以 go get就会失败。

新建一个批处理 goget.bat,放到 PATH 环境下。脚本如下:

@echo off
set http_proxy=socks5://127.0.0.1:10800
set https_proxy=socks5://127.0.0.1:10800
go get -u -v %*
echo ...
pause

https://tip.golang.org/cmd/cgo/

如何安装最新版

https://gomirrors.org/

If you have Go installed already, the easiest way to try go1.11beta3
is by using the go command:
$ go get golang.org/dl/go1.11beta3
$ go1.11beta3 download

You can download binary and source distributions from the usual place:
https://golang.org/dl/

To find out what has changed in Go 1.11, read the draft release notes:
https://tip.golang.org/doc/go1.11

1. Install golang https://dl.google.com

go1.10

  1. curl -O https://gomirrors.org/dl/go/go1.13.3.linux-amd64.tar.gz
  2. sudo rm -rf /usr/local/go && sudo tar -zxf go1.13.3.linux-amd64.tar.gz -C /usr/local

export GOROOT=/usr/local/go
echo "export PATH=\$PATH:$GOROOT/bin:$GOPATH/bin" | sudo tee /etc/profile.d/golang.sh > /dev/null

#set environment
export GOROOT=/usr/local/go
if ! grep "GOROOT=/usr/local/go" /etc/profile
then

    echo "export GOROOT=/usr/local/go" | sudo tee -a /etc/profile
    echo "export GOPROXY=https://goproxy.io" | sudo tee -a /etc/profile
    echo "export PATH=.:\$PATH:\$GOROOT/bin:\$GOPATH/bin" | sudo tee -a /etc/profile
fi
source /etc/profile
echo "golang is installed!"
  1. 环境变量配置

    GOROOT: golang可执行程序本身的路径
    GOPATH: 当有多个GOPATH时,默认会将go get的内容放在第一个目录下[golang库的路径]

    • Windows是[; 分号 semicolon-separated]
    • Linux系统是[: 冒号 colon-separated]

      GO113_GENERICS=on
      export GO15VENDOREXPERIMENT=1
      export GOROOT=/usr/local/go
      export GOPATH=$HOME/go
      export PATH=$PATH:$GOROOT/bin:$GOPATH/bin
      

跨平台编译 CGO_ENABLED=0

CGO_ENABLED=0 GOOS=linux go build -a -ldflags '-s -w'
CGO_ENABLED=0 go build -a -installsuffix cgo

go librarys

https://golang.org/pkg/
http://go-search.org/

Go命令详解

go env #查看GO变量

go build

如果是普通包,当你执行go build命令后,不会产生任何文件。
如果是main包,当只执行go build命令后,会在当前目录下生成一个可执行文件。
如果需要在$GOPATH/bin目录下生成相应的exe文件,需要执行go install 或者使用 go build -o 路径/a.exe

go install 命令在内部实际上分成了两步操作:

第一步是生成结果文件(可执行文件或者.a包),
第二步会把编译好的结果移到 $GOPATH/pkg 或者 $GOPATH/bin。

go get 命令本质上可以理解为:

先通过源码工具clone代码到src目录,然后执行go install; go get = git clone + go install
-insecure 使用http代理时
-d 只下载不安装
-f 只有在你包含了-u参数的时候才有效,不让-u去验证import中的每一个都已经获取了,这对于本地fork的包特别有用
-fix 在获取源码之后先运行fix,而后再进行编译和安装。
-t 同时也下载需要为运行测试所需要的包
-u 强制使用网络去更新包和它的依赖包 默认情况下,该命令只会从网络上下载本地不存在的代码包,而不会更新已有的代码包。 |
-v 显示执行的命令

go test 命令,会自动读取源码目录下面名为*_ test.go的文件,生成并运行测试用的可执行文件。输出的信息类似

解决go get无法获取golang.org的包的问题 x509 错误

while if I add --insecure option, it will be ok

设置代理,需要添加http_proxy等环境变量

修改~/.bashrc添加以下配置后,在source ~/.bashrc就可以了:

export http_proxy=http://localhost:8787
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy
export rsync_proxy=$http_proxy
export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"

此外git也需要配置代理:

git config --global https.proxy http://127.0.0.1:8787
git config --global https.proxy https://127.0.0.1:8787

查看已经设置的值:git config http.proxy

我们使用go get下载包时,最好使用-u -v参数,-v可以参看下载的其他依赖包,便于我们定位是哪个包出的问题,如:
go get -v -u github.com/kataras/iris
go get -v -u -insecure gopkg.in/yaml.v2

导入证书

Actually I have already imported related certs into /etc/ssl/certs/ca-certificates.crt before submitting this issue, and unfortunately without luck. Below is the steps what I do:

open firefox, and use the same proxy above: http://my-corporate-proxy:8080
navigate to "https://gopkg.in/yaml.v2", click upper left lock icon, and open "View Certificate"
export the cert to /usr/local/share/ca-certificates
run update-ca-certificates, and double check that /etc/ssl/certs/ca-certificates.crt does include this new cert

So seems go get doesn't recognise local certs? and still reports "certificate signed by unknown authority".

在中国网络环境下获取Golang.org上的Golang Packages

方法1:
golang.org被屏蔽了,直接访问不了,解决办法如下:
http://ping.eu/ping/ 上ping一下golang.org,获取到IP
方法2:
做下软连接把github文件夹下面的映射到golang.org下
ln -sf ~/go/src/github.com/golang ~/go/src/golang.org/x
ln -sf $GOPATH/src/github.com/golang $GOPATH/src/golang.org/x
ln -sf $GOPATH/src/github.com/go-gcfg/gcfg/gcfg $GOPATH/src/code.google.com/p/gcfg
ln -sf $GOPATH/src/github.com/go-gcfg/gcfg/gcfg $GOPATH/src/gopkg.in/gcfg.v1
code.google.com/p/gcfg
go get -d github.com/golang/sys
go get -d github.com/golang/tools
go get -d github.com/golang/net
go get -d github.com/golang/crypto
go get -d github.com/golang/mobile
go get -d github.com/golang/tour
go get -d github.com/golang/playground
go get -d github.com/golang/text
go get -d github.com/golang/image
go get -d github.com/golang/exp
go get -d github.com/golang/debug
go get -d github.com/golang/build
go get -d github.com/golang/time
go get -d github.com/golang/arch
go get -d github.com/golang/sync
go get -d github.com/golang/review
golang.org/x/time/rate

/home/ubuntu/go/src/google.golang.org
ln -sf ~/go/src/github.com/golang/grpc ~/go/src/google.golang.org/grpc
2.解决 appengine/cloudsql missing
google.golang.org/appengine/cloudsql
go get github.com/golang/appengine
ln -sf ~/go/src/github.com/golang/appengine ~/go/src/google.golang.org/appengine
ln -sb ~/go/src/github.com/golang/appengine ~/go/src/appengine
google.golang.org/grpc/transport

git clone https://github.com/grpc/grpc-go.git $GOPATH/src/google.golang.org/grpc
git clone https://github.com/golang/net.git $GOPATH/src/golang.org/x/net
git clone https://github.com/golang/text.git $GOPATH/src/golang.org/x/text
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}

git clone https://github.com/google/go-genproto.git $GOPATH/src/google.golang.org/genproto

go get github.com/google/go-genproto
ln -sb ~/go/src/github.com/google/go-genproto ~/go/src/google.golang.org/genproto
ln -sb ~/go/src/github.com/grpc/grpc-go ~/go/src/google.golang.org/grpc

cd $GOPATH/src/
go install google.golang.org/grpc

解决方案
方案 A: 使用github 上的镜像

获取Golang Package在github镜像上的路径:
golang.org/x/PATH_TO_PACKAGE —> github.com/golang/PATH_TO_PACKAGE.
golang.org/x/net/context --> github.com/golang/net/context

Go 包管理器

Golang package management archive

包管理工具:govendor

Install

go get -u -v github.com/kardianos/govendor

使用

export GO15VENDOREXPERIMENT=1

安装缺失的包

govendor fetch +missing

创建vendor

govendor init
govendor fetch golang.org/x/net/context
govendor add +missing

Add existing GOPATH files to vendor.

govendor add +external

View your work.

govendor list

Look at what is using a package

govendor list -v fmt

Specify a specific version or revision to fetch

govendor fetch golang.org/x/net/context@a4bbce9fcae005b22ae5443f6af064d80a6f5a55
govendor fetch golang.org/x/net/context@v1 # Get latest v1.. tag or branch.
govendor fetch golang.org/x/net/context@=v1 # Get the tag or branch named "v1".

Update a package to latest, given any prior version constraint

govendor fetch golang.org/x/net/context

Format your repository only

govendor fmt +local

Build everything in your repository only

govendor install +local

Test your repository only

govendor test +local

cd goproj & govendor init
goverdor --list
goverdor --list -v
Copy existing dependencies from $GOPATH with govendor add/update.
If you ignore vendor/* /, restore dependencies with govendor sync.
Pull in new dependencies or update existing dependencies directly from remotes with govendor fetch.
Migrate from legacy systems with govendor migrate.

go vendor 是go 1.5 官方引入管理包依赖的方式,1.6正式引入
go 1.6以后编译go代码会优先从vendor目录先寻找依赖包;
其基本思路是,将引用的外部包的源代码放在当前工程的vendor目录下面,

1.解决的问题:
将源码拷贝到当前工程的vendor目录下,这样打包当前的工程代码到任意机器的$GOPATH/src下都可以通过编译,避免项目代码外部依赖过多,迁移后,
需要多次go get 外包依赖包;而且通过go get 重新拉去的外部依赖包的版本可能和工程开发时使用的不一致,导致编译错误问题。

2.未解决的问题:
无法精确的引用外部包进行版本控制,不能指定引用某个特定版本的外部包;只是在开发时,将其拷贝过来,但是一旦外部包升级,vendor下的代码不会跟着升级,
而且vendor下面并没有元文件记录引用包的版本信息,这个引用外部包升级产生很大的问题,无法评估升级带来的风险;

3.解决go vendor未解决的问题 使用govendor ,其有如下好处:
https://github.com/kardianos/govendor
1>.可以平滑的将现有非vendor项目转换为vendor项目
govendor add inport_out_packagename
2>会生成一个元数据文件,记录项目工程依赖的外部包,以及其版本信息
vendor/vendor.json
3>提供命令查看整个工程的依赖关系
goverdor --list

goverdor --list -v

project:
https://github.com/kardianos/govendor

Sub-commands

init     Create the "vendor" folder and the "vendor.json" file.                 #创建一个vendor目录并生成个空的verdor.json文件
list     List and filter existing dependencies and packages.                    #查看已经存在的依赖包
add      Add packages from $GOPATH.                                             #把$GOPATH中的包拷贝到vendor目录下
update   Update packages from $GOPATH.                                          #把$GOPATH中的包更新到vendor目录下
remove   Remove packages from the vendor folder.                                #从vendor目录下移除外部依赖包
status   Lists any packages missing, out-of-date, or modified locally.          #查看缺失的或者本地修改的包
fetch    Add new or update vendor folder packages from remote repository.       #从远程代码库拉取依赖包到vendor目录
sync     Pull packages into vendor folder from remote repository with revisions #一句本地vendor/verdor.json文件指定的包机器版本信息从远程资源库拉取资源
             from vendor.json file.
migrate  Move packages from a legacy tool to the vendor folder with metadata.
get      Like "Go get" but copies dependencies into a "vendor" folder.          #等于go get 但是同步外部依赖包到vendor目录,而不是$GOPATH/src
license  List discovered licenses for the given status or import paths.
shell    Run a "shell" to make multiple sub-commands more efficient for large
             projects.


go tool commands that are wrapped:
  `+<status>` package selection may be used with them
fmt, build, install, clean, test, vet, generate, tool

Packages can be specified by their "status".

+local    (l) packages in your project
+external (e) referenced packages in GOPATH but not in current project
+vendor   (v) packages in the vendor folder
+std      (s) packages in the standard library
+excluded (x) external packages explicitely excluded from vendoring
+unused   (u) packages in the vendor folder, but unused
+missing  (m) referenced packages but not found
+program  (p) package is a main package


+outside  +external +missing
+all      +all packages


状态    缩写状态    含义
+local      l   本地包,即项目自身的包组织
+external   e   外部包,即被 $GOPATH 管理,但不在 vendor 目录下
+vendor       v     已被 govendor 管理,即在 vendor 目录下
+std          s     标准库中的包
+unused       u     未使用的包,即包在 vendor 目录下,但项目并没有用到
+missing      m     代码引用了依赖包,但该包并没有找到
+program      p     主程序包,意味着可以编译为执行文件
+outside          外部包和缺失的包
+all             所有的包

常见的命令如下,格式为 govendor COMMAND。

通过指定包类型,可以过滤仅对指定包进行操作。
命令  功能
init      初始化 vendor 目录
list      列出所有的依赖包
add       添加包到 vendor 目录,如 govendor add +external 添加所有外部包
add PKG_PATH    添加指定的依赖包到 vendor 目录
update  从 $GOPATH 更新依赖包到 vendor 目录
remove  从 vendor 管理中删除依赖
status  列出所有缺失、过期和修改过的包
fetch   添加或更新包到本地 vendor 目录
sync      本地存在 vendor.json 时候拉去依赖包,匹配所记录的版本
get       类似 go get 目录,拉取依赖包到 vendor 目录

glide使用 SegmentFault
glide简介

包管理工具:glide

curl https://glide.sh/get | sh
glide init
edit glide.yaml
glide update
glide install
glide get github.com/foo/bar#^1.2.3

glide 设置镜像 $HOME/.glide/mirrors.yaml

glide mirror set golang.org/x/crypto github.com/golang/crypto
golang.org/x/sys github.com/golang/sys
golang.org/x/tools github.com/golang/tools
golang.org/x/ github.com/golang/net
golang.org/x/ github.com/golang/crypto
golang.org/x/ github.com/golang/mobile
golang.org/x/ github.com/golang/tour
go get -d github.com/golang/playground
go get -d github.com/golang/text
go get -d github.com/golang/image
go get -d github.com/golang/exp
go get -d github.com/golang/debug
go get -d github.com/golang/build
go get -d github.com/golang/time
go get -d github.com/golang/arch
go get -d github.com/golang/sync
go get -d github.com/golang/review

golang.org/x/blog
golang.org/x/crypto
golang.org/x/exp
golang.org/x/image
golang.org/x/mobile
golang.org/x/net
golang.org/x/sys
golang.org/x/talks
golang.org/x/text
golang.org/x/tools

glide mirror set https://golang.org/x/mobile https://github.com/golang/mobile --vcs git
glide mirror set https://golang.org/x/crypto https://github.com/golang/crypto --vcs git
glide mirror set https://golang.org/x/net https://github.com/golang/net --vcs git
glide mirror set https://golang.org/x/tools https://github.com/golang/tools --vcs git
glide mirror set https://golang.org/x/text https://github.com/golang/text --vcs git
glide mirror set https://golang.org/x/image https://github.com/golang/image --vcs git
glide mirror set https://golang.org/x/sys https://github.com/golang/sys --vcs git

Go 语言包管理:gopm

go get -u github.com/gpmgo/gopm
list list all dependencies of current project
gen generate a gopmfile for current Go project
get fetch remote package(s) and dependencies
bin download and link dependencies and build binary
config configure gopm settings
run link dependencies and go run
test link dependencies and go test
build link dependencies and go build
install link dependencies and go install
clean clean all temporary files
update check and update gopm resources including itself
help, h Shows a list of commands or help for one command

包管理工具:godep

godep save

################################################################################

vscode调试工具:delve

go get github.com/derekparker/delve/cmd/dlv

anInt, _ = strconv.Atoi(origStr)
_ 无视错误
一个特殊的变量名是 _ (下划线)。任何赋给它的值都被丢弃。

多个defer的执行顺序为“后进先出”;
defer、return、返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入返回值中;接着defer开始执行一些收尾工作;最后函数携带当前返回值退出。

一个新定义的或者没有任何指向的指针,有值 nil。在其他语言中,这经常被叫做空(NULL)指针,在 Go 中就是 nil

import

1) import后面的最后一个元素应该是路径,就是目录,并非包名 使用的时包名
2) 同一个目录下只能有一个包名

匿名函数 (闭包)

赋值 fplus := func(x, y int) int { return x + y }
直接运行 func(x, y int) int { return x + y } (3, 4)

函数方法 类的内部方法 a.poll

func (a *Agent) Poll() error { return nil }

`