官术网_书友最值得收藏!

1.7 編程范例——啟動參數的使用

在前面的內容中,我們講述了開發環境的搭建,以及運行第一個實例程序,本節將通過實例——啟動參數的使用來進一步熟悉Go語言程序的基本編寫過程。

1.7.1 程序啟動的入口函數

在1.4.2節的代碼清單1-1中的包名和函數名均為main。對于一個Go程序的入口文件,其包名必須為main。例如,將代碼清單1-1中的包名修改為demo:

在修改后的代碼中,包名由main修改為了demo,此時無論是在GoLand直接利用菜單命令運行,還是在命令行使用go run命令,均無法正常運行,如下所示。

    $ go run 1-1.go
    package command-line-arguments is not a main package

但是文件1-1.go的編譯是可以順利通過的,這是因為此時的函數的完整引用名稱為demo.main(),編譯器只是將它視作一個普通函數,而非程序的執行入口。

同樣地,函數名main也是一個程序必需的,不能修改為其他名稱,否則程序也將無法成功執行。例如,將函數名main修改為demo,并嘗試使用go run命令運行,輸出結果如下:

    $ go run 1-1.go
    # command-line-arguments
    runtime.main_main·f: function main is undeclared in the main package

因此,我們可以總結出,即使一個最簡單的Go語言程序,函數main.main()是其入口的唯一標識,存在且只能存在一個main.main()函數。

1.7.2 獲取啟動參數

許多編程語言在程序入口函數中有參數定義,用于接收啟動時的個性化參數。例如,Java語言的參數接收方式有其固定格式:

    public static void main(String[] args){
    }

其中,參數args是一個String類型的數組。該參數按照順序接收命令行傳遞的參數。但是,Go語言使用了完全不同的策略——并沒有顯式的參數定義(例如前面的main.main()函數的定義中就沒有任何參數定義),而是使用固定函數來獲取命令行參數。

1.os.Args變量

os.Args是os包中定義的全局變量,其作用類似于Java語言main()方法中的args參數,其源碼定義如下:

    var Args []string

該變量是一個string類型的切片。當運行Go程序時,可以增加參數選項,這些參數將會被自動捕獲并填充到全局變量os.Args中。如此一來,我們便可以在程序中針對os.Args進行處理。代碼清單1-2演示了這一用法。

代碼清單1-2 利用os.Args變量獲取命令行參數

代碼解析:

(1)for i, arg := range os.Args,用于循環處理os.Args中的所有參數,其中變量i代表了每個參數的索引值,arg代表具體參數。

(2)fmt.Printf("參數%d = %s\n", i, arg),用于打印每個參數的索引和具體參數內容。Printf中的f代表Format,意為按一定格式打印;其中的%d和%s均為占位符,分別代表了數值格式和字符串格式。

可以利用如下命令進行測試:

    $ go run 1-2.go a b c

其中,go run 1-2.go為我們常用的運行命令,其后的a、b、c為附加參數,多個附加參數之間利用空格分隔。

該命令執行后,控制臺的輸出如下:

在輸出中,參數0為編譯后可執行文件的絕對路徑,無論有沒有附加參數,參數0都是默認存在的。顯式附加的參數a、b、c分別對應了參數1、參數2、參數3。

利用os.Args全局變量可以獲得附加參數列表,但是這種形式下,只能通過參數位置進行捕獲,這就非常依賴于參數順序的正確性。

2.os.Flag()函數

除了os.Args外,還可以利用flag.Int()、flag.Bool()、flag.String()等一系列os.Flag()函數來獲得參數。與os.Args依賴位置不同,os.Flag()函數可以按參數名獲得參數。代碼清單1-3演示了這一用法。

代碼清單1-3 利用os.Flag()函數獲得命令行參數

代碼解析:

(1)flag.Int("intVal", 0, "int類型參數"):用于獲取名為“intVal”的參數。flag.Int()會將參數視作int類型。其中的0代表如果參數未指定,則使用默認值0。

(2)類似地,flag.Bool("boolVal", false, "bool類型參數")和flag.String("stringVal", "", "string類型參數")分別用于獲得名為“boolVal”和“stringVal”的參數,其數據類型分別為布爾型和字符串類型。

(3)flag.Parse()是必需的步驟,用于解析以上參數。

如果在未指定任何參數的情況下運行該代碼段,將只輸出默認值,如下所示。

    $ go run 1-3.go
    -intVal: 0
    -boolVal: false
    -stringVal:

指定參數的命令也非常簡單,其使用格式如下:

    go run main.go -argName1 argVal1 -argName2 argVal2 ...

其中參數名(argName)和參數值(argVal)成對出現,例如-argName1 argVal1 -argName2 argVal2等。需要注意的是參數名之前的中畫線(-)不可省略。

可以利用如下命令執行1-3.go,并傳遞intVal、boolVal和stringVal參數的值:

    $ go run 1-3.go -intVal 15 -boolVal  -stringVal dev

在控制臺上的輸出如下:

    -intVal: 15
    -boolVal: true
    -stringVal: dev

可以看到,三個參數均已成功獲取到指定值。其中稍微有點特殊的是布爾類型的獲取,如果我們像其他參數形式一樣使用argName+argVal的形式,會發現其后的stringVal無法成功捕獲,如下所示。

    $ go run 1-3.go -intVal 15 -boolVal true  -stringVal dev
    -intVal: 15
    -boolVal: true
    -stringVal:

在輸出內容中,strintVal的值為空字符,即默認值。這是因為參數-boolVal true雖然在形式上與其他參數保持了一致性,但是對于布爾型參數解析(flag.Bool),單獨的“-boolVal”會被識別為一個參數;繼續解析時,會嘗試將“true”識別為參數名。但是,參數名必須要以“-”開頭,所以“true”被識別為非法的參數名,導致解析終止,后續字符串“-stringVal dev”的解析被忽略。

3.命令行參數的最優寫法

Go程序指定命令行參數時有以下4種形式可供選擇:

    -arg value

--arg value
-arg=value
--arg=value

但是布爾類型比較特殊,只以下支持兩種形式:

    -arg

-arg=value

因此,為了統一格式和避免不必要的問題,在使用命令行傳遞參數時,推薦使用-arg=value。調用代碼清單1-3的命令,使用如下形式是最佳選擇:

    $ go run 1-3.go -intVal=15 -boolVal=true  -stringVal=dev
    -intVal: 15
    -boolVal: true
    -stringVal: dev 
主站蜘蛛池模板: 庆云县| 屏南县| 宜阳县| 洪湖市| 镇原县| 娱乐| 沂水县| 阳江市| 资阳市| 淅川县| 临朐县| 盐城市| 铁力市| 北安市| 文安县| 河北区| 察雅县| 宜城市| 自贡市| 朝阳市| 永善县| 松滋市| 三都| 腾冲县| 林甸县| 牙克石市| 财经| 句容市| 叙永县| 淳安县| 蓝田县| 襄汾县| 台前县| 南宁市| 桃园县| 宁化县| 万盛区| 涞水县| 赤壁市| 浠水县| 京山县|