0

Calvert's murmur

 2 years ago
source link: https://calvertyang.github.io/2021/09/16/go-command-line-flags-options/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

原文:CalliCoderGo Command-line flags/options

命令列程式通常會接受來自使用者的旗標或選項來自訂指令的執行。旗標是在執行指令時加在指令名稱後的鍵值對。

Go 允許你使用標準函式庫中的 flags package 來接收命令列旗標。在本文中,你將學到如何為命令列程式接收旗標。

Go 的命令列旗標

要接收命令列旗標,你需要定義旗標以便從命令列取值。你可以透過多種方式做到:

  1. 使用 flag.String()flag.Bool()flag.Int() 等方法定義旗標。
  2. 使用 flag.StringVar(), flag.IntVar() 等方法將現有變數綁定到命令列旗標。
  3. 透過宣告一個實作 flag.Value 介面的類型來建立自訂旗標,然後使用 flag.Var() 方法將自訂類型的變數與命令列旗標綁定。

讓我們在以下範例中看看前兩種方法。我們會在其他範例看到第三種方法。

package main

import (
	"flag"
	"fmt"
	"strings"
)

func main() {
	// Declare a string flag called name with a default value ("Guest") and a help message
	name := flag.String("name", "Guest", "specify your name")

	// Declare a flag called age with default value of 0 and a help message
	age := flag.Int("age", 0, "specify your age")

	// Bind the command-line flag with an existing variable
	var country string
	flag.StringVar(&country, "country", "", "enter your country")

    // Enable command-line parsing
	flag.Parse()

	fmt.Printf("Hello %s\n", *name)
	fmt.Printf("Your age is %d\n", *age)
	fmt.Printf("Your are from %s\n", country)
}
# Build the program
$ go build command-line-flags.go

使用 -h 或 --help 旗標來取得命令列程式的輔助說明

$ ./command-line-flags -h
Usage of ./command-line-flags:
  -age int
    	specify your age
  -country string
    	enter your country
  -name string
    	specify your name (default "Guest")

使用空格分隔的鍵值對提供旗標

$ ./command-line-flags -name Rajeev -age 28 -country India
Hello Rajeev
Your age is 28
Your are from India

使用 鍵=值 的格式提供旗標

$ ./command-line-flags -name=Rajeev -age=28 -country="United Kingdom"
Hello Rajeev
Your age is 28
Your are from United Kingdom

如果未指定,則旗標使用預設值

$ ./command-line-flags -age=24 -country="United States"
Hello Guest
Your age is 24
Your are from United States

建立自訂命令列旗標

以下範例示範了如何建立自訂旗標。在這個範例中,我們定義並解析以逗號分隔的命令列旗標。

package main

import (
	"flag"
	"fmt"
	"strings"
)

// A custom type that implements the flag.Value interface
type hobbies []string

func (h *hobbies) String() string {
	return fmt.Sprint(*h)
}

func (h *hobbies) Set(value string) error {
	for _, hobby := range strings.Split(value, ",") {
		*h = append(*h, hobby)
	}
	return nil
}

func main() {
    // Define a custom flag
	var hobbiesFlag hobbies
	flag.Var(&hobbiesFlag, "hobbies", "comma separated list of hobbies")

    // Enable command-line parsing
	flag.Parse()

	fmt.Printf("Your hobbies are: ")
	for _, hobby := range hobbiesFlag {
		fmt.Printf("%s ", hobby)
	}
	fmt.Println()
}
# Output
$ ./command-line-flags -hobbies=Sports,Photography,Coding
Your hobbies are: Sports Photography Coding

使用旗標 package 處理位置引數

flag.Parse() 函數會持續解析它遇到的旗標,直到它偵測到非旗標引數(位置引數)。旗標 package 透過 Args()Arg() 函數讓你可以使用位置引數。

請注意,旗標 package 要求所有旗標都出現在位置引數之前。否則,旗標會被直譯為位置引數。

讓我們來看一個位置引數的範例。假設我們正在撰寫一個程式,用來在檔案中的起始行號到結束行號搜尋給定的關鍵字清單。在以下範例中,我們接受作為旗標的起始和結束行號,以及作為位置引數的關鍵字清單:

package main

import (
	"flag"
	"fmt"
)

func main() {
	s := flag.Int("s", 0, "start line number")
    t := flag.Int("t", 0, "end line number")

	// Enable command-line parsing
	flag.Parse()

	fmt.Printf("Search file from line number %d to %d\n", *s, *t)

    // Read all the positional arguments
	fmt.Println("for keywords:", flag.Args())

    // Read the i'th positional argument
	i := 0
	fmt.Printf("The keyword at index %d: %v\n", i, flag.Arg(i))
}

以下是向程式提供旗標和非旗標引數的方法:

$ go build command-line-flags.go

$ ./command-line-flags -s 1 -t 100 Go Java
Search file from line number 1 to 100
for keywords: [Go Java]
The keyword at index 0: Go

你必須在位置引數之前指定旗標。否則,旗標也會被直譯為位置引數:

$ ./command-line-flags Go Java -s 1 -t 100
Search file from line number 0 to 0
for keywords: [Go Java -s 1 -t 100]
The keyword at index 0: Go

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK