初探go-golang语言初体验

前端之家收集整理的这篇文章主要介绍了初探go-golang语言初体验前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

初探go-golang语言初体验

2017/10/20



一、初体验
1、环境
wgethttps://storage.googleapis.com/golang/go1.8.linux-amd64.tar.gz
tar-C/usr/local-xzfgo1.8.linux-amd64.tar.gz

cat<<'_EOF'>>/etc/profile
#golang
exportPATH=$PATH:/usr/local/go/bin
exportGOPATH=/opt/go
_EOF

source/etc/profile


2、教程
#gotooltour&
访问:http://127.0.0.1:3999/


3、第一个程序
#cd$GOPATH
#mkdirsrc/abc.com/demo/hello-p
#vimsrc/abc.com/demo/hello/hello.go
packagemain

import"fmt"

funcmain(){
fmt.Printf("Hello,world.\n")
}


#goinstallabc.com/demo/hello
#bin/hello
Hello,world.


4、第一个包
#mkdirsrc/abc.com/demo/stringutil-p
#vimsrc/abc.com/demo/stringutil/reverse.go
//Packagestringutilcontainsutilityfunctionsforworkingwithstrings.
packagestringutil

//Reversereturnsitsargumentstringreversedrune-wiselefttoright.
funcReverse(sstring)string{
	r:=[]rune(s)
	fori,j:=0,len(r)-1;i<len(r)/2;i,j=i+1,j-1{
		r[i],r[j]=r[j],r[i]
	}
	returnstring(r)
}

#gobuildabc.com/demo/stringutil
#catsrc/abc.com/demo/hello/hello.go
packagemain

import(
	"fmt"

	"abc.com/demo/stringutil"
)

funcmain(){
	fmt.Printf(stringutil.Reverse("!oG,olleH"))
}

#goinstallabc.com/demo/hello
#bin/hello
Hello,Go!


5、目录结构
#tree/opt/go
/opt/go
├──bin#install后生成的可执行文件目录
│└──hello
├──pkg#install后生成的包目录
│└──linux_amd64
│└──abc.com
│└──demo
│└──stringutil.a
└──src#源码目录
└──abc.com
└──demo
├──hello
│└──hello.go
└──stringutil
└──reverse.go

10directories,4files


6、引入测试
#vimsrc/abc.com/demo/stringutil/reverse_test.go
packagestringutil

import"testing"

funcTestReverse(t*testing.T){
	cases:=[]struct{
		in,wantstring
	}{
		{"Hello,world","dlrow,olleH"},{"Hello,世界","界世,{"",""},}
	for_,c:=rangecases{
		got:=Reverse(c.in)
		ifgot!=c.want{
			t.Errorf("Reverse(%q)==%q,want%q",c.in,got,c.want)
		}
	}
}

#gotestabc.com/demo/stringutil
okabc.com/demo/stringutil0.007s



7、使用远程的包
示例,从git上指定的url获取包,goget将完成fetch,build和install的操作:
#gogetgithub.com/golang/example/hello
#bin/hello
Hello,Goexamples!


8、查看当前go的环境变量
[root@tvm01go]#goenv
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/opt/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC-m64-pthread-fmessage-length=0-fdebug-prefix-map=/tmp/go-build679741147=/tmp/go-build"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g-O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g-O2"
CGO_FFLAGS="-g-O2"



9、重新编译go源码

1)源码
需求:使用goget的时候,看不到下载的进度条。
目标:调整go源码,重新编译

[root@tvm01src]#pwd
/usr/local/go/src
[root@tvm01src]#vimcmd/go/vcs.go
varvcsGit=&vcsCmd{
(略)
createCmd:[]string{"clone{repo}{dir}","-go-internal-cd{dir}submoduleupdate--init--recursive"},downloadCmd:[]string{"pull--ff-only","submoduleupdate--init--recursive"},变更为:
createCmd:[]string{"clone--progress{repo}{dir}",(略)

func(v*vcsCmd)run1(dirstring,cmdlinestring,keyval[]string,verbosebool)([]byte,error){
(略)
cmd.Stdout=&buf
cmd.Stderr=&buf

变更为:
cmd.Stdout=&buf
cmd.Stderr=&buf
cmd.Stdout=os.Stdout
cmd.Stderr=os.Stderr
(略)


2)编译
[root@tvm01src]#./all.bash
#####BuildingGobootstraptool.
cmd/dist
ERROR:$GOROOT_BOOTSTRAPmustnotbesetto$GOROOT
Set$GOROOT_BOOTSTRAPtoaworkingGotree>=Go1.4.


解决办法:编译go1.4,然后再重试
unsetGOPATH
unsetGOROOT


cd/opt
mkdirgo1.4_src
gitclonehttps://github.com/golang/go.git
cdgo
gitcheckout-b1.4.3go1.4.3
cdsrc
./all.bash
cd../..
cp-ago/root/go1.4
cd/usr/local/go

[root@tvm01src]#./all.bash


重新测试:
[root@tvm01src]#source/etc/profile

[root@tvm01src]#goget-vgithub.com/docker/docker/client
github.com/docker/docker(download)
Cloninginto'/opt/go/src/github.com/docker/docker'...
remote:Countingobjects:234999,done.
remote:Compressingobjects:100%(24/24),done.
Receivingobjects:6%(15150/234999),4.64MiB|345.00KiB/s


符合预期。




二、试着写一个小的程序
1、设定目标
1)尽量多的用到go语言的语法基础内容:packages,variables,functionsFlowcontrol,method,interface,concurrency
2)请求url,获取状态等;


2、代码示例
[root@tvm01go]#catsrc/abc.com/demo/demoHttpHead/app.go
/*
#demoHttpHead
#2017/10/20
*/

packagemain

import(
"flag"
"fmt"
"log"
"sync"
"time"
"net/http"
"io/IoUtil"
"strings"
"strconv"
)


typetaskStatestruct{
vmap[string]int
muxsync.Mutex
}

func(ts*taskState)Inc(keystring){
ts.mux.Lock()
ts.v[key]++
ts.mux.Unlock()
}

func(ts*taskState)Value(keystring)int{
ts.mux.Lock()
deferts.mux.Unlock()
returnts.v[key]
}


funchandleError(errerror,methodstring)bool{
iferr!=nil{
log.Printf("[E]%s:%v",err)
returntrue
}
returnfalse
}


funcgetHosts()([]string){
varhosts[]string
data,err:=IoUtil.ReadFile("urls.txt")
ifhandleError(err,"IoUtil.ReadFile"){
returnhosts
}

for_,h:=rangestrings.Split(string(data),"\n"){
ifh==""{
continue
}
hosts=append(hosts,h)
}
returnhosts
}


funchandleHttpHeadReq(seqint,urlstring,chchanstring,stat*taskState){
head,err:=http.Head(url)
ifhandleError(err,"http.Head"){
stat.Inc("failure")

ch<-"["+strconv.Itoa(seq)+"]"+url+":Failed."
return
}

stat.Inc("success")
status:=head.Status
ch<-"["+strconv.Itoa(seq)+"]"+url+":"+status
}


funcmain(){
dtStart:=time.Now()
cnt:=flag.Int("c",10,"[]setNtimestorequestthehttpurl.")
fromCfg:=flag.Bool("f",false,"[]parseurlsfromfile:[urls.txt]ornot?")

flag.Parse()

varstat=taskState{v:make(map[string]int)}
varhosts[]string

if*fromCfg==true{
hosts=getHosts()
}else{
hosts=flag.Args()
}

for_,url:=rangehosts{
ch:=make(chanstring)
fori:=0;i<*cnt;i++{
gohandleHttpHeadReq(i,url,ch,&stat)
}

fort:=0;t<*cnt;t++{
fmt.Println(<-ch)
}
}
log.Printf("success:%d,failure:%d,TimeCost:%v\n",stat.Value("success"),stat.Value("failure"),time.Since(dtStart))
}




3、如何运行
1)直接运行
[root@tvm01go]#gorunsrc/abc.com/demo/http_status/http_status.go-h
Usageof/tmp/go-build822199343/command-line-arguments/_obj/exe/http_status:
-cint
[]setNtimestorequestthehttpurl.(default10)
-f[]parseurlsfromfile:[urls.txt]ornot?
exitstatus2

[root@tvm01go]#gorunsrc/abc.com/demo/demoHttpHead/app.go-c3http://www.baidu.com
[2]http://www.baidu.com:200OK
[0]http://www.baidu.com:200OK
[1]http://www.baidu.com:200OK
2017/10/2011:12:15success:3,failure:0,TimeCost:20.514834ms

[root@tvm01go]#gorunsrc/abc.com/demo/demoHttpHead/app.go-c3http://www.baidu.comhttp://www.taobao.com
[2]http://www.baidu.com:200OK
[0]http://www.baidu.com:200OK
[1]http://www.baidu.com:200OK
[2]http://www.taobao.com:200OK
[1]http://www.taobao.com:200OK
[0]http://www.taobao.com:200OK
2017/10/2011:12:33success:6,TimeCost:131.9136ms



2)编译
当前为linux环境
[root@tvm01go]#goinstallabc.com/demo/demoHttpHead
运行
[root@tvm01go]#./bin/demoHttpHead-h
Usageof./bin/demoHttpHead:
-cint
	[]setNtimestorequestthehttpurl.(default10)
-f	[]parseurlsfromfile:[urls.txt]ornot?

[root@tvm01go]#./bin/demoHttpHead-c5http://www.taobao.com
[3]http://www.taobao.com:200OK
[2]http://www.taobao.com:200OK
[1]http://www.taobao.com:200OK
[0]http://www.taobao.com:200OK
[4]http://www.taobao.com:200OK
2017/10/2011:13:37success:5,TimeCost:107.063734ms



3)交叉编译
以windows平台为例:
[root@tvm01go]#GOOS="windows"goinstallabc.com/demo/demoHttpHead
[root@tvm01go]#szbin/windows_amd64/abc.com/demo/demoHttpHead.exe
下载到windows下执行,符合预期






三、FAQ
1、访问golang.org异常

注1:引用【docker深入2-UI之portainer的二次开发】文章的实例

构建app

[root@dev_08portainer]#gruntbuild

如果遇到这样的错误:
Buildingportainerforlinux-amd64
/go/src/github.com/portainer/portainer/crypto/crypto.go:4:2:cannotfindpackage"golang.org/x/crypto/bcrypt"inanyof:
	/usr/local/go/src/golang.org/x/crypto/bcrypt(from$GOROOT)
	/go/src/golang.org/x/crypto/bcrypt(from$GOPATH)
/go/src/github.com/portainer/portainer/http/handler/websocket.go:21:2:cannotfindpackage"golang.org/x/net/websocket"inanyof:
	/usr/local/go/src/golang.org/x/net/websocket(from$GOROOT)
	/go/src/golang.org/x/net/websocket(from$GOPATH)
mv:cannotstat‘api/cmd/portainer/portainer-linux-amd64’:Nosuchfileordirectory
Warning:CommandFailed:build/build_in_container.shlinuxamd64
mv:cannotstat‘api/cmd/portainer/portainer-linux-amd64’:Nosuchfileordirectory
Use--forcetocontinue.

Abortedduetowarnings.

那是因为网络可达性问题,国内访问golang.org异常。
[root@dev_08portainer]#hostgolang.org
golang.orgisanaliasforgolang-consa.l.google.com.
golang-consa.l.google.comhasaddress216.239.37.1


导致这2个依赖下载失败:
golang.org/x/crypto/bcrypt
golang.org/x/net/websocket


解决方法:
[root@dev_08portainer]#gogetgithub.com/golang/crypto/tree/master/bcrypt
[root@dev_08portainer]#gogetgithub.com/golang/net/tree/master/websocket

[root@dev_08portainer]#cd$GOPATH/src
[root@dev_08src]#mkdirgolang.org/x-p
[root@dev_08src]#mvgithub.com/golang/*golang.org/x/


然后再切换到源码目录,调整构建脚本:
[root@dev_08src]#cd/opt/portainer
[root@dev_08portainer]#vimbuild/build_in_container.sh
挂载本地的$GOPATH/src/golang.org到容器路径:/go/src/golang.org

dockerrun--rm-tv$(pwd)/api:/src-eBUILD_GOOS="$1"-eBUILD_GOARCH="$2"portainer/golang-builder:cross-platform/src/cmd/portainer

调整为:

dockerrun--rm-tv$(pwd)/api:/src-v$GOPATH/src/golang.org:/go/src/golang.org-eBUILD_GOOS="$1"-eBUILD_GOARCH="$2"portainer/golang-builder:cross-platform/src/cmd/portainer


最后重新构建一次:
[root@dev_08portainer]#gruntbuild
(略)
Cleaning"dist/js/angular.37dfac18.js"...OK
Cleaning"dist/js/portainer.cab56db9.js"...OK
Cleaning"dist/js/vendor.4edc9b0f.js"...OK
Cleaning"dist/css/portainer.e7f7fdaa.css"...OK

Done,withouterrors.


看到上述输出,表示符合预期。






XYXW、参考
1、golang
https://golang.org/doc
https://golang.org/doc/code.html#Workspaces

2、the-way-to-go_ZH_CN
https://github.com/Unknwon/the-way-to-go_ZH_CN/blob/master/eBook/directory.md

3、解决升级go版本遇到的Set$GOROOT_BOOTSTRAPtoaworkingGotree>=Go1.4.问题
http://blog.csdn.net/qq_15437667/article/details/59776840

4、国内下载golang.org的包有什么好办法么?
https://gocn.io/question/362

猜你在找的Go相关文章