GO语言的进阶之路-go的程序结构以及包简介

               GO语言的进阶之路-go的程序结构以及包简介

                                      作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

 

一.编辑,编译和运行
A,编辑  
  Go程序使用UTF-8编码的纯Unicode文本编写。大部分现代编译器都能够自动处理编码,并且某些最流行的编辑器还支持Go语言的语法高亮和自动缩进。如果你用的编辑器不支持Go语言,可以在Go语言官网的搜索框中输入编辑器的名字,看看是否有适合的插件可用。为了编辑方便,所有的Go语言关键字和操作符都使用ASCII编码字符,但是Go语言中标识符可以是任一Unicode编码字符后跟若干Unicode字符或数字,这样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 }
myecho.go的具体内容

 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 }
原文地址:https://www.cnblogs.com/yinzhengjie/p/7000272.html