GO语言的进阶之路-go的程序结构以及包简介
GO语言的进阶之路-go的程序结构以及包简介
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
B,编译
说道编译,我们不得不了解2个命令,一个是"go build",另外一个是“go install”。
前者大家应该都很熟悉,因为我在上一篇(http://www.cnblogs.com/yinzhengjie/p/6482675.html)关于GO的博客中用"go build"命令编译不同的版本,但是在这里我们还是要演示一下go build的花式用法。
1 package main 2 3 import ( 4 "os" 5 "fmt" 6 ) 7 8 func main() { 9 var s,sep string 10 for i := 1; i < len(os.Args);i++{ 11 s += sep + os.Args[i] 12 sep = " " 13 } 14 fmt.Println(s) 15 }
1.go build后加参数
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 在命令行中执行go build + [go文件],那么久会生成一个可执行的二进制文件, 9 ''' 10 [root@yinzhengjie day2]# ll 11 total 4 12 -rw-r--r-- 1 root root 165 Jun 13 14:45 myecho.go 13 [root@yinzhengjie day2]# 14 [root@yinzhengjie day2]# go build myecho.go 15 [root@yinzhengjie day2]# ll 16 total 1520 17 -rwxr-xr-x 1 root root 1551621 Jun 13 15:11 myecho 18 -rw-r--r-- 1 root root 165 Jun 13 14:45 myecho.go 19 [root@yinzhengjie day2]#
2.go build后不加参数
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 在命令行中执行:go build命令,如果不加任何参数的话,它就会把当前目录下的所有go文件统一进行编译,如果这些文件编译没有出错的话, 9 成功编译后会生成一个以当前目录问名字的二进制文件。 10 ''' 11 12 [root@yinzhengjie day2]# ll 13 total 4 14 -rw-r--r-- 1 root root 165 Jun 13 14:45 myecho.go 15 [root@yinzhengjie day2]# 16 [root@yinzhengjie day2]# go build 17 [root@yinzhengjie day2]# 18 [root@yinzhengjie day2]# ll 19 total 1520 20 -rwxr-xr-x 1 root root 1551621 Jun 13 15:15 day2 21 -rw-r--r-- 1 root root 165 Jun 13 14:45 myecho.go 22 [root@yinzhengjie day2]# ./day2 111 222 333 23 111 222 333 24 [root@yinzhengjie day2]#
要注意的是,以上编译出来的文件,我们可以将其放在"$GOPATH/bin目录下"这样我们就可以在任何目录下执行编译出来的那个文件名字啦,前提是你的"$PATH"设置的是OK的!
当你会用"go build"命令的话,其实"go install"就更简单了。但是首先你要知道为什么会用go install这个命令!我们在编译一个文件的时候用“go build”命令是很好使的,没有必要用“go install”这个命令,但是一个目录下有好多过go文件的话,我们应该咋办呢?这个时候用"go install"的优势就体现出来了。它会把当前目录(我们可以理解这个目录其实就是一个package)所有的go文件都进行编译。他和"go build”唯一明显的区别就是:"多做了一个mv的操作,也就是说用'go build'命令编译出来的代码最终会在当前目录下生成一个文件,而'go install'命令就会将生成的这个文件移动到$GOPATH/bin目录下。"这样方便你在任何路径下动都可以使用你编译好的文件程序。
不得不说的是,在用"go install"这个命令时,你不得不对"package"进行了解,在命令行敲击这个命令的时候你需要检查以你的环境。如果环境配置正确的话,是不会报错的!
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 'go install'和"go build”唯一明显的区别就是:"多做了一个mv的操作,也就是说用'go build'命令编译出来的代码最终会在当前目录下生成 9 一个文件,而'go install'命令就会将生成的这个文件移动到$GOPATH/bin目录下。这样方便你在任何路径下动都可以使用你编译好的文件程序。 10 ''' 11 12 [root@yinzhengjie day2]# go env #查看go的环境变量 13 GOARCH="amd64" 14 GOBIN="/yinzhengjie/go_file/bin" #配置的bin目录 15 GOEXE="" 16 GOHOSTARCH="amd64" 17 GOHOSTOS="linux" 18 GOOS="linux" 19 GOPATH="/yinzhengjie/go_file" #项目存放目录 20 GORACE="" 21 GOROOT="/yinzhengjie/golang/local/go" #go程序安装目录 22 GOTOOLDIR="/yinzhengjie/golang/local/go/pkg/tool/linux_amd64" 23 GCCGO="gccgo" 24 CC="gcc" 25 GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0" 26 CXX="g++" 27 CGO_ENABLED="1" 28 PKG_CONFIG="pkg-config" 29 CGO_CFLAGS="-g -O2" 30 CGO_CPPFLAGS="" 31 CGO_CXXFLAGS="-g -O2" 32 CGO_FFLAGS="-g -O2" 33 CGO_LDFLAGS="-g -O2" 34 [root@yinzhengjie day2]#
注意,以上是查看go环境,但是这些参数具体在哪里配置呢?有很多定义系统变量的文件都可以,我用的是"~/.bash_profile"这个文件来进行编辑的,具体配置我们只需要在这个文件中添加以下几行就OK啦:
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 export GOROOT=/yinzhengjie/golang/local/go 8 export GOPATH=/yinzhengjie/go_file 9 export PATH=$GOROOT/bin:$GOPATH/bin:$PATH 10 export GOBIN=$GOPATH/bin
其实,要想使用“go install”命令的话,我们需要手动指定一个在$GOPATH目录下手动创建一个"src"目录。然后在这个src目录下创建你的子目录,也可以说是不同的项目,当你在这个不同的项目中使用“go install”命令时,会在$GOPATH的bin目录下自动生成一个文件,以便你全局调用这个程序文件。
1.go install后不跟参数用法
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 [root@yinzhengjie day2]# ll 8 total 4 9 -rw-r--r-- 1 root root 165 Jun 13 17:25 myecho.go 10 [root@yinzhengjie day2]# 11 [root@yinzhengjie day2]# go install 12 [root@yinzhengjie day2]# 13 [root@yinzhengjie day2]# ls 14 myecho.go 15 [root@yinzhengjie day2]# day2 111 222 333 16 111 222 333 17 [root@yinzhengjie day2]#
2.go install跟参数用法
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 [root@yinzhengjie day2]# ll 8 total 4 9 -rw-r--r-- 1 root root 165 Jun 13 17:25 myecho.go 10 [root@yinzhengjie day2]# 11 [root@yinzhengjie day2]# go install myecho.go 12 [root@yinzhengjie day2]# 13 [root@yinzhengjie day2]# myecho 666 777 888 14 666 777 888 15 [root@yinzhengjie day2]#
C.运行
相比大家玩过shell的人应该都是如果想要一个脚本直接在服务器上跑起来,需要给他家执行权限,但是没有执行权限的话也要运行这个脚本,我们可以用"sh + [脚本名]"照样是可以运行的。
那么在go程序中要使得go程序跑起来我们应该如何操作呢?其实我们有两种方法,一种就是类似于shell那样,不给这个go文件添加执行权限,用"go run或者gonow"命令来运行这个脚本;还有一种方法就是用“go build”命令将这个go文件编译成一个二进制可执行文件,然后在命令行中直接运行即可。
1.go run 用法展示
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 [root@yinzhengjie day2]# ll 8 total 4 9 -rw-r--r-- 1 root root 165 Jun 13 17:25 myecho.go 10 [root@yinzhengjie day2]# go run myecho.go 111 222 333 11 111 222 333 12 [root@yinzhengjie day2]#
2.go build用法展示
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 [root@yinzhengjie day2]# ll 8 total 4 9 -rw-r--r-- 1 root root 165 Jun 13 17:25 myecho.go 10 [root@yinzhengjie day2]# go build myecho.go 11 [root@yinzhengjie day2]# 12 [root@yinzhengjie day2]# ll 13 total 1520 14 -rwxr-xr-x 1 root root 1551621 Jun 13 17:38 myecho 15 -rw-r--r-- 1 root root 165 Jun 13 17:25 myecho.go 16 [root@yinzhengjie day2]# ./myecho 333 555 888 17 333 555 888 18 [root@yinzhengjie day2]#
二.package那些事
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 1.做一个项目一般不会用一个文件就搞定了,可能需要多个文件才能搞定,这个时候我们就需要引入一个概念,即package, 9 这个包里面可以存放多个go文件。 10 2.一个package只能有一个main函数; 11 3.同一个目录下的go文件只能是一个package(换句话说,同一个目录下go文件中的package后面的关键字必须一样。); 12 4.同一个package下的目录可以共享变量;同一个package下的目录可以共享函数; 13 5.两种package,一种是库package,一种是二进制package.二进制package使用 main 来表示,库package的名字跟go文件所 14 在的目录名一样. 15 16 '''
1.同个目录下引用其他包的变量
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 package的一个好处就是将你的代码按照文件进行处置,不同文件完成不同的事情, 9 ''' 10 11 ''' 12 [root@yinzhengjie myecho]# ll 13 total 8 14 -rw-r--r-- 1 root root 184 Jun 14 15:24 myecho.go 15 -rw-r--r-- 1 root root 48 Jun 14 15:24 name.go 16 [root@yinzhengjie myecho]# 17 [root@yinzhengjie myecho]# more name.go 18 package main 19 20 var name string = "yinzhengjie" 21 [root@yinzhengjie myecho]# 22 [root@yinzhengjie myecho]# more myecho.go 23 package main 24 25 import ( 26 "os" 27 "fmt" 28 ) 29 30 func main() { 31 var s,sep string 32 for i := 1; i < len(os.Args);i++{ 33 s += sep + os.Args[i] 34 sep = " " 35 } 36 fmt.Println(s) 37 fmt.Println(name) #虽然在当前文件中没有定义name变量,照样可以用! 38 } 39 40 [root@yinzhengjie myecho]# 41 [root@yinzhengjie myecho]# pwd 42 /yinzhengjie/go_file/src/day2/myecho 43 [root@yinzhengjie myecho]# 44 [root@yinzhengjie myecho]# go install 45 [root@yinzhengjie myecho]# 46 [root@yinzhengjie myecho]# myecho 666666 47 666666 48 yinzhengjie #这个是字符串。 49 [root@yinzhengjie myecho]# 50 51 '''
2.引入自定义的package案例展示
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 [root@yinzhengjie golib]# pwd //模拟创建一个第三方包为"golib"包 9 /yinzhengjie/go_file/src/day1/golib 10 [root@yinzhengjie golib]# 11 [root@yinzhengjie golib]# ll 12 total 4 13 -rw-r--r-- 1 root root 59 Jun 15 09:48 math.go 14 [root@yinzhengjie golib]# 15 [root@yinzhengjie golib]# more math.go 16 package golib //这个目录下的所有package关键字后面必须都跟"golib"参数。 17 18 func Add(a int,b int) int { 19 return a + b 20 } 21 [root@yinzhengjie golib]# 22 [root@yinzhengjie testlib]# pwd 23 /yinzhengjie/go_file/src/day2/testlib 24 [root@yinzhengjie testlib]# 25 [root@yinzhengjie testlib]# ll 26 total 4 27 -rw-r--r-- 1 root root 94 Jun 15 09:46 import_package.go 28 [root@yinzhengjie testlib]# 29 [root@yinzhengjie testlib]# more import_package.go //创建一个脚本用于测试导入第三方库。 30 package main 31 import ( 32 "fmt" 33 "day1/golib" //需要写“src”目录下的绝对路径,导入"golib"的package. 34 ) 35 36 func main(){ 37 fmt.Println(golib.Add(100,200)) 38 } 39 [root@yinzhengjie testlib]# 40 [root@yinzhengjie testlib]# go install 41 [root@yinzhengjie testlib]# testlib 42 300 43 [root@yinzhengjie testlib] 44 45 '''
3.查询package说明文档
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 也许你知道通过官网查询第三方包说明文档,比如要查看os,就在浏览器的地址栏输入:"https://godoc.org/os"这个 9 网址你就能看到相应的说明了,但是如果这个package是你自定义的,你们公司要用你的 程序,你需要写一个说明文档供应 10 大家查看。这个时候我们就用到了一个比较神奇的工具,“godoc”工具可以启动服务器的一个web端口。 11 ''' 12 13 ''' 14 [root@yinzhengjie golib]# pwd 15 /yinzhengjie/go_file/src/day1/golib 16 [root@yinzhengjie golib]# 17 [root@yinzhengjie golib]# 18 [root@yinzhengjie golib]# ll 19 total 4 20 -rw-r--r-- 1 root root 94 Jun 15 10:07 math.go 21 [root@yinzhengjie golib]# 22 [root@yinzhengjie golib]# more math.go 23 package golib 24 25 26 //ADD return a + b by yinzhengjie 27 func Add(a int,b int) int { 28 return a + b 29 } 30 [root@yinzhengjie golib]# 31 [root@yinzhengjie ~]# godoc -http=:8000 & #表示启动本地的服务器8000端口供大家查看你自定义的package! 32 [1] 29084 33 [root@yinzhengjie ~]# 34 [root@yinzhengjie ~]# ip a | grep eth | grep inet | awk '{print $2}' | awk -F "/" '{print $1}' #查看当前服务器的IP,只需要在web上输入"IP:端口"即可 35 172.16.3.211 36 [root@yinzhengjie ~]# 37 '''
下面我们就需要在web端输入相应的地址即可:“http://172.16.3.211:8000/doc/”
a>.点击package
b>.找到了你自定义的package,查看相关信息即可。
c>.点击你自定义的包名,查看其内容说明即可。
以上的操作是告诉我们如何在本地实现如何让大家访问,那么如何把你的代码推送到github上去呢?可以参考我的笔记:http://www.cnblogs.com/yinzhengjie/p/7017036.html。如果你需要用到第三方模块在别人的github账号的仓库里,那么我们可以先把他们的环境项目下载下来,然后在引用他们的代码。配置起来也特别简单,就两条命令的事情。
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 [root@yinzhengjie testlib]# ll $GOPATH 9 total 8 10 drwxr-xr-x 2 root root 4096 Jun 15 14:10 bin 11 drwxr-xr-x 5 root root 4096 Jun 15 12:16 src 12 [root@yinzhengjie testlib]# 13 [root@yinzhengjie testlib]# go get github.com/yinzhengjie/golib #将github上的项目下载到本地的GOPATH环境变量中, 14 [root@yinzhengjie testlib]# 15 [root@yinzhengjie testlib]# ll $GOPATH 16 total 12 17 drwxr-xr-x 2 root root 4096 Jun 15 14:10 bin 18 drwxr-xr-x 3 root root 4096 Jun 15 14:16 pkg 19 drwxr-xr-x 5 root root 4096 Jun 15 12:16 src 20 [root@yinzhengjie testlib]# 21 [root@yinzhengjie src]# ll 22 total 12 23 drwxr-xr-x 4 root root 4096 Jun 15 09:40 day1 24 drwxr-xr-x 3 root root 4096 Jun 15 09:43 day2 25 drwxr-xr-x 3 root root 4096 Jun 15 12:16 github.com #多出来的项目 26 [root@yinzhengjie src]# pwd 27 /yinzhengjie/go_file/src 28 [root@yinzhengjie src]# 29 [root@yinzhengjie testlib]# more import_package.go 30 package main 31 import ( 32 "fmt" 33 "github.com/yinzhengjie/golib" //我们可以导入下载后的第三方库 34 ) 35 36 func main(){ 37 fmt.Println(golib.Add(100,200)) 38 } 39 [root@yinzhengjie testlib]# 40 '''
好了,经过上面的案例,大家也许已经看出来Golang关于package的特点,我总结如下:
A.从package的角度来说:
1>.首先,该package必须是在GOPATH路径下;
2>.一个package可用存在多个“*.go”文件,但是每个“*.go”文件的开头第一行必须是其package + 名称(你可以理解是代码存放的目录名称)。
3>.一个package可用存在多个“*.go”文件,但是每个“*.go”文件的开头第一行必须是其package + mian 。但是要注意的是在这个目录下的所有“*.go”文件中只能存在一个main函数。
B.从调用的角度来说:
1>.调用时,需要从GOPATH路径中的src目录(你可以理解成是库的根目录)下的第一个目录开始写,直到写到包名的路径为止。
2>.调用的时候,你的代码可以在操作系统的任何路径下调用。
扩展小知识:
在一个新的服务器上GOPATH目录下新建了一个src目录,但是初次从github下载一个模块的时候,会在src目录下生成一个pkg目录,这个目录是干嘛用的呢?
答案:pkg是编译的中间产物。编译分为编译->链接的过程,“pkg”里面放的是编译的产物,二进制是链接的产物。如果干掉这个“pkg”目录后还会自动生成,具体缓存的作用。具体的信息可以问问我的大师兄和二师兄。
三.代码风格
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 1.所有的代码只有一种,gofmt的风格; 9 2.gofmt 不是任何人的风格,但所有人都喜欢 gofmt 的风格; 10 3.使用 `gofmt -w xx.go` 来格式化代码; 11 '''
四.命令行参数
我们以后再开发命令行工具就会少不了跟命令行参数打交道,所以这些基本的这是我们得掌握清楚。
1 [root@yinzhengjie day2]# pwd 2 /yinzhengjie/go_file/src/day2 3 [root@yinzhengjie day2]# 4 [root@yinzhengjie day2]# ll 5 total 12 6 -rw-r--r-- 1 root root 178 Jun 15 15:41 args.go 7 -rw-r--r-- 1 root root 184 Jun 14 15:21 myecho.go 8 -rw-r--r-- 1 root root 48 Jun 14 15:21 name.go 9 [root@yinzhengjie day2]# 10 [root@yinzhengjie day2]# go run args.go 111 222 333 11 [/tmp/go-build716596169/command-line-arguments/_obj/exe/args 111 222 333] 12 first 111 13 second 222 14 third 333 15 [root@yinzhengjie day2]# 16 [root@yinzhengjie day2]# go build args.go 17 [root@yinzhengjie day2]# 18 [root@yinzhengjie day2]# ./args 111 222 333 19 [./args 111 222 333] 20 first 111 21 second 222 22 third 333 23 [root@yinzhengjie day2]# 24 [root@yinzhengjie day2]# 25 [root@yinzhengjie day2]# more args.go 26 package main 27 28 import ( 29 "fmt" 30 "os" 31 ) 32 33 func main() { 34 fmt.Println(os.Args) 35 fmt.Println("first",os.Args[1]) 36 fmt.Println("second",os.Args[2]) 37 fmt.Println("third",os.Args[3]) 38 } 39 [root@yinzhengjie day2]#
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 [root@yinzhengjie day2]# more myecho.go 9 package main 10 11 import ( 12 "os" 13 "fmt" 14 ) 15 16 func main() { 17 var s,sep string 18 for i := 1; i < len(os.Args);i++{ 19 s += sep + os.Args[i] 20 sep = " " 21 } 22 fmt.Println(s) 23 } 24 25 [root@yinzhengjie day2]# 26 [root@yinzhengjie day2]# 27 [root@yinzhengjie day2]# go run myecho.go 1 22 333 28 1 22 333 29 [root@yinzhengjie day2]# 30 31 32 '''
想必大家都用过cat命令,我们想要用cat命令去查看服务器信息,我们就可以用命令行参数帮我们简单时间一下这个功能。
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 [root@yinzhengjie day2]# more cat.go #用go写的cat程序代码 9 package main 10 11 import ( 12 "io/ioutil" 13 "fmt" 14 "os" 15 ) 16 17 func main() { 18 var s string 19 for i := 1; i < len(os.Args); i++ { 20 s = os.Args[i] 21 printFile(s) 22 } 23 24 fmt.Println("yinzhengjie") 25 } 26 27 func printFile(name string) { 28 buf, err := ioutil.ReadFile(name) 29 if err != nil { 30 fmt.Println(err) 31 return 32 } 33 fmt.Println(string(buf)) 34 } 35 36 37 [root@yinzhengjie day2]# 38 You have new mail in /var/spool/mail/root 39 [root@yinzhengjie day2]# 40 [root@yinzhengjie day2]# more 111 41 11111111111111111111111111111 42 yinzhengjie 43 11111111111111111111111111111 44 [root@yinzhengjie day2]# more 2222 45 222222222222222222222222222 46 yinzhengjie 47 222222222222222222222222222 48 [root@yinzhengjie day2]# more 3333 49 3333333333333333333333333333 50 yinzhengjie 51 3333333333333333333333333333 52 [root@yinzhengjie day2]# 53 [root@yinzhengjie day2]# 54 [root@yinzhengjie day2]# go run cat.go 111 2222 3333 #执行代码运行结果如下 55 11111111111111111111111111111 56 yinzhengjie 57 11111111111111111111111111111 58 59 222222222222222222222222222 60 yinzhengjie 61 222222222222222222222222222 62 63 3333333333333333333333333333 64 yinzhengjie 65 3333333333333333333333333333 66 67 yinzhengjie 68 [root@yinzhengjie day2]# 69 70 '''
五.变量声明
1.定义全局变量。
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 package main 9 10 //1.定义变量的风格,定义一个数字类型变量x, 11 var x int 12 13 //2.定义变量的类型为字符串y,其值等于“yinzhengjie” 14 var y string = "yinzhengjie" 15 16 //3.当然我们可以同时定义2个变量的类型都为自数字,不用一行一行的写 17 var x, y int 18 19 //4.当然,如果你定义的变量类型比较多的话,也可以这么晚 20 var ( 21 x int 22 y int 23 z string 24 ) 25 26 27 '''
2.定义局部变量
#!/usr/bin/env python #_*_coding:utf-8_*_ #@author :yinzhengjie #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ #EMAIL:y1053419035@qq.com ''' package main import "fmt" func main() { x := 100 s := "yinzhengjie" fmt.Println(x,s) x,y := 200,300 fmt.Println(x,y) } ''' #以上代码执行结果如下: 100 yinzhengjie 200 300
六.零值初始化
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 package main 9 10 import "fmt" 11 12 func main() { 13 var ( 14 x int #定义是整数型变量 15 y float32 #定义是浮点数的变量 16 z string #定义是字符串的变量 17 p *int #定义的是指针类型的变量 18 q bool #定义是布尔值的变量 19 ) 20 fmt.Println("x =",x) 21 fmt.Println("y =",y) 22 fmt.Println("z =",z) 23 fmt.Println("p =",p) 24 fmt.Println("q =",q) 25 } 26 27 28 ''' 29 30 31 32 #以上代码执行结果如下: 33 x = 0 34 y = 0 35 z = 36 p = <nil> 37 q = false
七.指针
1 //@author :yinzhengjie 2 //blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 3 //EMAIL:y1053419035@qq.com 4 5 ''' 6 指针总结如下: 7 1>.*T 即为类型T的指针 8 2>.&t 即为取变量t的地址 9 3>.*p 即为取指针变量所指向的内容 10 ''' 11 12 13 package main 14 15 import "fmt" 16 17 func main() { 18 var x int //定义x的变量的类型为int 19 var p *int //表示p为int类型的指针 20 fmt.Println(&x) //取变量x的内存地址 21 p = &x 22 fmt.Println("P==",p) 23 fmt.Println("*P==",*p) //表示取变量p的内容,要区别其与"*int",“*string”,"*float32"哟 24 } 25 26 27 28 29 30 31 32 33 以上代码执行结果如下: 34 0xc04203e1d0 35 P== 0xc04203e1d0 36 *P== 0
学习完指针和命令行参数,我们就可以简单的写一个关于echo的小脚本,我们可以进行如下的模拟实验。当然,我们需要用到flag这个package,来帮我完成这个脚本,具体内容如下:
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #@author :yinzhengjie 4 #blog:http://www.cnblogs.com/yinzhengjie/tag/python%E8%87%AA%E5%8A%A8%E5%8C%96%E8%BF%90%E7%BB%B4%E4%B9%8B%E8%B7%AF/ 5 #EMAIL:y1053419035@qq.com 6 7 ''' 8 [root@yinzhengjie day2]# more myflag.go 9 package main 10 import ( 11 "flag" 12 "fmt" 13 "strings" 14 ) 15 var sep = flag.String("s", " ", "separator") #表示用"-s"指定隔离每个参数的关键字 16 var newline = flag.Bool("n",false,"append newline") #表示用“-n”指定是否换行 17 18 func main() { 19 flag.Parse() 20 fmt.Print(strings.Join(flag.Args(), *sep)) 21 if *newline { 22 fmt.Println() 23 } 24 } 25 [root@yinzhengjie day2]# 26 [root@yinzhengjie day2]# go run myflag.go -s % -n My name is yinzhengjie #换行结果 27 My%name%is%yinzhengjie 28 [root@yinzhengjie day2]# 29 [root@yinzhengjie day2]# 30 [root@yinzhengjie day2]# go run myflag.go -s %% My name is yinzhengjie #为换行结果 31 My%%name%%is%%yinzhengjie[root@yinzhengjie day2]# 32 [root@yinzhengjie day2]# 33 '''
八.作用域
关于全局作用域和局部作用域估计大家都清楚吧,这个概念很简单,不知道小伙伴自行百度一下吧,学习过其他语言的童鞋应该知道这个基础的东西,下面就让我们一起学习一下,看看Golang语言是不是也是如此呢?
1 /* 2 #!/usr/bin/env gorun 3 @author :yinzhengjie 4 Blog:http://www.cnblogs.com/yinzhengjie/tag/GO%E8%AF%AD%E8%A8%80%E7%9A%84%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/ 5 EMAIL:y1053419035@qq.com 6 */ 7 8 package main 9 10 import "fmt" 11 12 var x int = 200 13 14 func localFunc() { 15 fmt.Println(x) 16 } 17 18 func main() { 19 x := 1 20 localFunc() //打印数字200,因为该函数中和他同级的是全局变量x = 200 21 fmt.Println(x) //打印数字1,他在寻找变量的时候回从同级找,从缩进来看,都是在main函数内部的作用于,有x = 1的变量,故打印出来了 22 if true { 23 x := 100 //给x变量赋初值,也就是我们说的短变量,要注意的是它仅在局部变量使用,在全局变量使用会报错。 24 fmt.Println(x) //打印数字100,因为它还是会从它同级开始找,从if语句开始,然后再到main函数,再到全局变量一次向外查询。 25 } 26 27 localFunc() //打印数字200,因为该函数中和他同级的是全局变量x = 200,道理一样,这个localFunc函数回去它同级作用域(对于该函数而已就是全局变量中)找,找到就打印,找不到就报错。 28 fmt.Println(x) //打印数字1,还是在它的同级作用域查找,其同级作用域就是缩进相同的变量或函数或者条件表达式等等。 29 }