提示:本系列文章適合有其他語音基礎並對Go有持續衝動的讀者
一、package介紹
Go語言的程式碼是通過package來組織的,package的概念和你知道的其它語言 裡的libraries或者modules概念比較類似。
一個package會包含一個或多個.go結束的原始碼檔案。每一 個原始檔都是以一個package xxx的宣告語句開頭的,比如我們的例子裡就是package main。這行宣告語 句表示該檔案是屬於哪一個package,緊跟著是一系列import的package名,表示這個檔案中引入的 package。再之後是本檔案本身的程式碼。
package main是一個比較特殊的package。這個package裡會定義一個獨立的程式,這個程式是可以執行 的,而不是像其它package一樣對應一個library。
這也正是因為go語言必須引入所有要用到的package的原則,假如你沒有在程式碼裡import需要用到的 package,程式將無法編譯通過,同時當你import了沒有用到的package,也會無法編譯通過。
二、命令列引數
os這個package提供了作業系統無關(跨平臺)的,與系統互動的一些函式和相關的變數,執行時程式的 命令列引數可以通過os包中一個叫Args的變數來獲取;當在os包外部使用該變數時,需要用os.Args來訪問。
os.Args的第一個元素,即os.Args[0]是命令列執行時的命令本身;其它的元素則是執行該命令時傳給這 個程式的引數。前面提到的切片表示式,s[m:n]會返回第m到第n-1個元素,所以下一個例子裡需要用到 的os.Args[1:len(os.Args)]即是除了命令本身外的所有傳入引數。如果我們省略s[m:n]裡的m和n,那麼 預設這個表示式會填入0:len(s),所以這裡我們還可以省略掉n,寫成os.Args[1:]。
1.輸出命令列引數
// go 中命令列引數的使用
package main
import (
"fmt"
"os"
)
func main() {
var s, seq string
seq = " "
for i := 1; i < len(os.Args); i++ {
s += os.Args[i] + seq
}
fmt.Println(s)
}
[root@VM-0-5-centos course1]# go run lesson-1.go hello world
hello world
2.關於迴圈
在Go語言裡只有for迴圈
一種迴圈。
for initialization; condition; post {
// zero or more statements
}
// a traditional "while" loop
for condition {
// ...
}
// a traditional infinite loop
for {
// ...
}
range
每次迴圈迭代,range
產生一對值;索引以及在該索引處的元素值。這個例子不需要索引,但range
的語法要求, 要處理元素, 必須處理索引。一種思路是把索引賦值給一個臨時變數, 如temp
, 然後忽略它的值,但Go語言不允許使用無用的區域性變數(local variables),因為這會導致編譯錯誤。
Go語言中這種情況的解決方法是用空識別符號
(blank identifier),即_
(也就是下劃線)。空識別符號可用於任何語法需要變數名但程式邏輯不需要的時候, 例如, 在迴圈裡,丟棄不需要的迴圈索引, 保留元素值。大多數的Go程式設計師都會像上面這樣使用range
和_
寫echo
程式,因為隱式地而非顯式地索引os.Args,容易寫對。
package main
import (
"fmt"
"os"
)
func main() {
var s string
seq := " "
for _, arg := range os.Args[1:] {
s += arg + seq
}
fmt.Println(s)
}
strings.Join連線引數
package main
import (
"fmt"
"os"
"strings"
)
func main() {
var s string
s = strings.Join(os.Args[1:], " ")
fmt.Println(s)
fmt.Println(os.Args[1:]) //切片的方式輸出
}
[root@VM-0-5-centos course1]# go run join.go wo apple ibm cisco
wo apple ibm cisco
[wo apple ibm cisco]
三、 練習
練習 1.1: 修改echo
程式,使其列印每個引數的索引和值,每個一行。
package main
import (
"fmt"
"os"
)
func main() {
var s string
seq := " "
for index, arg := range os.Args[1:] {
s += arg + seq
//fmt.Println("yees" + s)
fmt.Println(index, arg)
}
//fmt.Println(s)
}
練習 1.2: 修改echo
程式,使其能夠列印os.Args[0]
,即被執行命令本身的名字。
package main
import (
"fmt"
"os"
)
func main() {
var s string
seq := " "
for index, arg := range os.Args[1:] {
s += arg + seq
//fmt.Println("yees" + s)
fmt.Println(index, arg)
}
fmt.Println(os.Args[0])
}
//output
[root@VM-0-5-centos course1]# go run for_range.go apple ibm
0 apple
1 ibm
/tmp/go-build844979177/b001/exe/for_range
練習 1.3: 做實驗測量潛在低效的版本和使用了strings.Join
的版本的執行時間差異。(time包)
//for迴圈遍歷
package main
import (
"fmt"
"os"
"time"
)
func main() {
var s, seq string
seq = " "
var start_time = time.Now()
for i := 1; i < len(os.Args); i++ {
s += os.Args[i] + seq
}
fmt.Println(s)
end_time := time.Now()
fmt.Println(end_time.Sub(start_time))
}
[root@VM-0-5-centos course1]# go run comandline.go apple ibm
apple ibm
19.667µs
//join連線
package main
import (
"fmt"
"os"
"strings"
"time"
)
func main() {
var s string
start_time := time.Now()
s = strings.Join(os.Args[1:], " ")
fmt.Println(s)
//fmt.Println(os.Args[1:])
end_time := time.Now()
fmt.Println(end_time.Sub(start_time))
}
[root@VM-0-5-centos course1]# go run join.go apple ibm
apple ibm
16.782µs
書籍參考:Go語言聖經中文版
文章有不足的地方歡迎在評論區指出。
歡迎收藏、點贊、提問。關注頂級飲水機管理員,除了管燒熱水,有時還做點別的。