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 }