溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Go語(yǔ)言中怎么讀取命令參數(shù)

發(fā)布時(shí)間:2022-04-14 16:18:59 來(lái)源:億速云 閱讀:169 作者:iii 欄目:編程語(yǔ)言

今天小編給大家分享一下Go語(yǔ)言中怎么讀取命令參數(shù)的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

本文講述使用三種方式講述 Go 語(yǔ)言如何接受命令行參數(shù),并完成一個(gè)簡(jiǎn)單的數(shù)學(xué)計(jì)算,為演示方便,最后的命令行結(jié)果大概是這樣的:

# input 
./calc add 1 2
# output
3

# input
./calc sub 1 2
# out
-1

# input
./calc mul 10 20
# out
200

使用的三種方式是:

  • 內(nèi)置 os 包讀取命令參數(shù)

  • 內(nèi)置 flag 包讀取命令參數(shù)

  • cli 框架讀取命令參數(shù)

0. 已有歷史經(jīng)驗(yàn)

如果你熟悉 Python 、Shell 腳本,你可以比較下:

Python

import sys

args = sys.argv

# args 是一個(gè)列表
# 第一個(gè)值表示的是 文件名
# 除第一個(gè)之外,其他的值是接受的參數(shù)

Shell

if [ $# -ne 2 ]; then
 echo "Usage: $0 param1 pram2"
 exit 1
fi
name=$1
age=$2

echo $name
echo $age
# `$0` 表示文件名
# `$1` 表示第一個(gè)參數(shù)
# `$2` 表示第二個(gè)參數(shù)

能看出一些共性,接收參數(shù),一般解析出來(lái)都是一個(gè)數(shù)組(列表、切片), 第一個(gè)元素表示的是文件名,剩余的參數(shù)表示接收的參數(shù)。

好,那么為了實(shí)現(xiàn) “簡(jiǎn)單數(shù)學(xué)計(jì)算” 這個(gè)功能,讀取命令行參數(shù):比如 ./calc add 1 2

除文件名之外的第一個(gè)元素:解析為 進(jìn)行數(shù)學(xué)運(yùn)算的 操作,比如: add、sub、mul、sqrt
其余參數(shù)表示:進(jìn)行操作的數(shù)值

注意:命令行讀取的參數(shù)一般為字符串,進(jìn)行數(shù)值計(jì)算需要進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換

大概思路就是這樣。

1. OS 獲取命令行參數(shù)

os.Args

# 為接受的參數(shù),是一個(gè)切片

strconv.Atoi 

# 將字符串?dāng)?shù)值轉(zhuǎn)換為整型

strconv.Itoa

# 將整型轉(zhuǎn)換為字符串

strconv.ParseFloat

# 將字符串?dāng)?shù)值轉(zhuǎn)換為浮點(diǎn)型
var help = func () {
 fmt.Println("Usage for calc tool.")
 fmt.Println("====================================================")
 fmt.Println("add 1 2, return 3")
 fmt.Println("sub 1 2, return -1")
 fmt.Println("mul 1 2, return 2")
 fmt.Println("sqrt 2, return 1.4142135623730951")
}


func CalcByOs() error {
 args := os.Args
 if len(args) < 3 || args == nil {
 help()
 return nil
 }
 operate := args[1]
 switch operate {
 case "add":{
  rt := 0
  number_one, err1 := strconv.Atoi(args[2])
  number_two, err2 := strconv.Atoi(args[3])
  if err1 == nil && err2 == nil {
  rt = number_one + number_two
  fmt.Println("Result ", rt)
  }
 }
 case "sub":
 {
  rt := 0
  number_one, err1 := strconv.Atoi(args[2])
  number_two, err2 := strconv.Atoi(args[3])
  if err1 == nil && err2 == nil {
  rt += number_one - number_two
  fmt.Println("Result ", rt)
  }
 }
 case "mul":
 {
  rt := 1
  number_one, err1 := strconv.Atoi(args[2])
  number_two, err2 := strconv.Atoi(args[3])
  if err1 == nil && err2 == nil {
  rt = number_one * number_two
  fmt.Println("Result ", rt)
  }
 }
 case "sqrt":
 {
  rt := float64(0)
  if len(args) != 3 {
  fmt.Println("Usage: sqrt 2, return 1.4142135623730951")
  return nil
  }
  number_one, err := strconv.ParseFloat(args[2], 64)
  if err == nil {
  rt = math.Sqrt(number_one)
  fmt.Println("Result ", rt)
  }
 }
 default:
 help()

 }
 return nil
}

最后的效果大概是:

./calc add 1 2
Result 3

====================

./calc sub 1 2
Result -1

====================

./calc mul 10 20
Result 200

===================

./calc sqrt 2
Result 1.4142135623730951

2. flag 獲取命令行參數(shù)

flag 包比 os 讀取參數(shù)更方便??梢宰远x傳入的參數(shù)的類型:比如字符串,整型,浮點(diǎn)型,默認(rèn)參數(shù)設(shè)置等

基本的使用方法如下:

var operate string

flag.StringVar(&operate,"o", "add", "operation for calc")

# 解釋

綁定 operate 變量, name="o", value="add" , usage="operation for calc"

也可以這樣定義為指針變量

var operate := flag.String("o", "add", "operation for calc")

同時(shí)還可以自定義 flag 類型

所有變量注冊(cè)之后,調(diào)用 flag.Parse() 來(lái)解析命令行參數(shù), 如果是綁定變量的方式,直接使用變量進(jìn)行操作,
如果使用指針變量型,需要 *operate 這樣使用。

flag.Args() 表示接收的所有命令行參數(shù)集, 也是一個(gè)切片

for index, value := range flag.Args {
 fmt.Println(index, value)
}
func CalcByFlag() error {
 var operation string
 var numberone float64
 var numbertwo float64
 flag.StringVar(&operation, "o", "add", "operation for this tool")
 flag.Float64Var(&numberone, "n1", 0, "The first number")
 flag.Float64Var(&numbertwo, "n2", 0, "The second number")
 flag.Parse()
 fmt.Println(numberone, numbertwo)
 if operation == "add" {
 rt := numberone + numbertwo
 fmt.Println("Result ", rt)
 } else if operation == "sub" {
 rt := numberone - numbertwo
 fmt.Println("Result ", rt)
 } else if operation == "mul" {
 rt := numberone * numbertwo
 fmt.Println("Result ", rt)
 } else if operation == "sqrt" {
 rt := math.Sqrt(numberone)
 fmt.Println("Result ", rt)
 } else {
 help()
 }
 return nil
}

最后的結(jié)果效果如下:

./calc -o add -n1 1 -n2 2
Result 3

=============================

./calc -o sub -n1 2 -n2 3
Result -1

============================

./calc -o mul -n1 10 -n2 20
Result 200

===========================

./calc -o sqrt -n1 2
Result 1.4142135623730951

3. CLI 框架

cli 是一款業(yè)界比較流行的命令行框架。

所以你首先需要安裝:

go get github.com/urfave/cli
# 一個(gè)簡(jiǎn)單的示例如下:
package main

import (
 "fmt"
 "os"

 "github.com/urfave/cli"
)

func main() {
 app := cli.NewApp()
 app.Name = "boom"
 app.Usage = "make an explosive entrance"
 app.Action = func(c *cli.Context) error {
 fmt.Println("boom! I say!")
 return nil
 }

 app.Run(os.Args)
}

好,為實(shí)現(xiàn) “簡(jiǎn)單數(shù)學(xué)計(jì)算” 的功能,我們應(yīng)該怎么實(shí)現(xiàn)呢?

主要是 使用 框架中的 Flag 功能,對(duì)參數(shù)進(jìn)行設(shè)置

app.Flags = []cli.Flag {
 cli.StringFlag{
 Name: "operation, o",
 Value: "add",
 Usage: "calc operation",
 },
 cli.Float64Flag{
 Name: "numberone, n1",
 Value: 0,
 Usage: "number one for operation",
 },
 cli.Float64Flag{
 Name: "numbertwo, n2",
 Value: 0,
 Usage: "number two for operation",
 },
}

能看出,我們使用了三個(gè)參數(shù):operation、numberone、numbertwo

同時(shí)定義了參數(shù)的類型,默認(rèn)值,以及別名(縮寫(xiě))

那么在這個(gè)框架中如何實(shí)現(xiàn)參數(shù)的操作呢:主要是重寫(xiě)app.Action 方法

app.Action = func(c *cli.Context) error {
 operation := c.String("operation")
 numberone := c.Float64("numberone")
 numbertwo := c.Float64("numbertwo")
 //fmt.Println(operation, numberone, numbertwo)
 if operation == "add" {
 rt := numberone + numbertwo
 fmt.Println("Result ", rt)
 } else if operation == "sub" {
 rt := numberone - numbertwo
 fmt.Println("Result ", rt)
 } else if operation == "mul" {
 rt := numberone * numbertwo
 fmt.Println("Result ", rt)
 } else if operation == "sqrt" {
 rt := math.Sqrt(numberone)
 fmt.Println("Result ", rt)
 } else {
 help()
 }
 return nil
}

# 對(duì) operation 參數(shù)進(jìn)行判斷,執(zhí)行的是那種運(yùn)算,然后編寫(xiě)相應(yīng)的運(yùn)算操作
func CalcByCli(){
 app := cli.NewApp()
 app.Name = "calc with go"
 app.Usage = "calc tool operate by go"
 app.Version = "0.1.0"
 app.Flags = [] cli.Flag {
  cli.StringFlag{
   Name: "operation, o",
   Value: "add",
   Usage: "calc operation",
  },
  cli.Float64Flag{
   Name: "numberone, n1",
   Value: 0,
   Usage: "number one for operation",
  },
  cli.Float64Flag{
   Name: "numbertwo, n2",
   Value: 0,
   Usage: "number two for operation",
  },
 }
 app.Action = func(c *cli.Context) error {
  operation := c.String("operation")
  numberone := c.Float64("numberone")
  numbertwo := c.Float64("numbertwo")
  //fmt.Println(operation, numberone, numbertwo)
  if operation == "add" {
   rt := numberone + numbertwo
   fmt.Println("Result ", rt)
  } else if operation == "sub" {
   rt := numberone - numbertwo
   fmt.Println("Result ", rt)
  } else if operation == "mul" {
   rt := numberone * numbertwo
   fmt.Println("Result ", rt)
  } else if operation == "sqrt" {
   rt := math.Sqrt(numberone)
   fmt.Println("Result ", rt)
  } else {
   help()
  }
  return nil
 }
 app.Run(os.Args)
}

調(diào)用這個(gè)函數(shù)的最終效果如下:

./calc -o add --n1 12 --n2 12
Result 24

===================================

./calc -o sub --n1 100 --n2 200
Result -100

===================================

./calc -o mul --n1 10 --n2 20
Result 200

===================================

./calc -o sqrt --n1 2
Result 1.4142135623730951

4 其他

知道如何讀取命令行參數(shù),就可以實(shí)現(xiàn)一些更有意思的事。

比如網(wǎng)上有許多免費(fèi)的 API 接口,比如查詢天氣,查詢農(nóng)歷的API 接口。

還有一些查詢接口,比如有道云翻譯接口,你可以實(shí)現(xiàn)翻譯的功能。

或者扇貝的接口,實(shí)現(xiàn)查詢單詞的功能。

再比如一些音樂(lè)接口,實(shí)現(xiàn)音樂(lè)信息查詢。

不一一列了。

下面實(shí)現(xiàn)一個(gè)調(diào)用免費(fèi)的查詢天氣的接口實(shí)現(xiàn)命令行查詢天氣。

GO 如何進(jìn)行 HTTP 訪問(wèn)??jī)?nèi)置的 net/http 可以實(shí)現(xiàn)

一個(gè)簡(jiǎn)易的GET 操作如下:

func Requests(url string) (string, error) {
 response, err := http.Get(url)
 if err != nil {
  return "", err
 }
 defer response.Body.Close()
 body, _ := ioutil.ReadAll(response.Body)
 return string(body), nil
}

免費(fèi)的 API URL 如下:

http://www.sojson.com/open/api/weather/json.shtml?city=北京

返回的結(jié)果是一個(gè)Json 格式的數(shù)據(jù)

{
 "status": 200,
 "data": {
  "wendu": "29",
  "ganmao": "各項(xiàng)氣象條件適宜,發(fā)生感冒機(jī)率較低。但請(qǐng)避免長(zhǎng)期處于空調(diào)房間中,以防感冒。",
  "forecast": [
   {
    "fengxiang": "南風(fēng)",
    "fengli": "3-4級(jí)",
    "high": "高溫 32℃",
    "type": "多云",
    "low": "低溫 17℃",
    "date": "16日星期二"
   },
   {
    "fengxiang": "南風(fēng)",
    "fengli": "微風(fēng)級(jí)",
    "high": "高溫 34℃",
    "type": "晴",
    "low": "低溫 19℃",
    "date": "17日星期三"
   },
   {
    "fengxiang": "南風(fēng)",
    "fengli": "微風(fēng)級(jí)",
    "high": "高溫 35℃",
    "type": "晴",
    "low": "低溫 22℃",
    "date": "18日星期四"
   },
   {
    "fengxiang": "南風(fēng)",
    "fengli": "微風(fēng)級(jí)",
    "high": "高溫 35℃",
    "type": "多云",
    "low": "低溫 22℃",
    "date": "19日星期五"
   },
   {
    "fengxiang": "南風(fēng)",
    "fengli": "3-4級(jí)",
    "high": "高溫 34℃",
    "type": "晴",
    "low": "低溫 21℃",
    "date": "20日星期六"
   }
  ],
  "yesterday": {
   "fl": "微風(fēng)",
   "fx": "南風(fēng)",
   "high": "高溫 28℃",
   "type": "晴",
   "low": "低溫 15℃",
   "date": "15日星期一"
  },
  "aqi": "72",
  "city": "北京"
 },
 "message": "OK"
}

所以我們的任務(wù)就是傳入 “城市” 的名稱,再對(duì)返回的 Json 數(shù)據(jù)解析。

package main

import (
  "fmt"
  "os"
 "encoding/json"
  "github.com/urfave/cli"
  "net/http"
  "io/ioutil"
  //"github.com/modood/table"
)
type Response struct {
  Status int `json:"status"`
  CityName string `json:"city"`
  Data  Data `json:"data"`
  Date  string `json:"date"`
  Message string `json:"message"`
  Count int `json:"count"`
}

type Data struct {
  ShiDu  string `json:"shidu"`
  Quality string `json:"quality"`
  Ganmao string `json:"ganmao"`
  Yesterday Day `json:"yesterday"`
  Forecast []Day `json:"forecast"`
}

type Day struct {
  Date string `json:"date"`
  Sunrise string `json:"sunrise"`
  High string `json:"high"`
  Low  string `json:"low"`
  Sunset string `json:"sunset"`
  Aqi  float32 `json:"aqi"`
  Fx  string `json:"fx"`
  Fl  string `json:"fl"`
  Type string `json:"type"`
  Notice string `json:"notice"`
}

func main() {
  const apiURL = "http://www.sojson.com/open/api/weather/json.shtml?city="
  app := cli.NewApp()
  app.Name = "weather-cli"
  app.Usage = "天氣預(yù)報(bào)小程序"

  app.Flags = []cli.Flag{
    cli.StringFlag{
      Name: "city, c",
      Value: "上海",
      Usage: "城市中文名",
    },
    cli.StringFlag{
      Name: "day, d",
      Value: "今天",
      Usage: "可選: 今天, 昨天, 預(yù)測(cè)",
    },
    cli.StringFlag{
      Name: "Author, r",
      Value: "xiewei",
      Usage: "Author name",
    },
  }

  app.Action = func(c *cli.Context) error {
    city := c.String("city")
    day := c.String("day")

    var body, err = Requests(apiURL + city)
    if err != nil {
      fmt.Printf("err was %v", err)
      return nil
    }

    var r Response
    err = json.Unmarshal([]byte(body), &r)
    if err != nil {
      fmt.Printf("\nError message: %v", err)
      return nil
    }
    if r.Status != 200 {
      fmt.Printf("獲取天氣API出現(xiàn)錯(cuò)誤, %s", r.Message)
      return nil
    }
    Print(day, r)
    return nil
  }
  app.Run(os.Args)

}


func Print(day string, r Response) {
  fmt.Println("城市:", r.CityName)
  if day == "今天" {
    fmt.Println("濕度:", r.Data.ShiDu)
    fmt.Println("空氣質(zhì)量:", r.Data.Quality)
    fmt.Println("溫馨提示:", r.Data.Ganmao)
  } else if day == "昨天" {
    fmt.Println("日期:", r.Data.Yesterday.Date)
    fmt.Println("溫度:", r.Data.Yesterday.Low, r.Data.Yesterday.High)
    fmt.Println("風(fēng)量:", r.Data.Yesterday.Fx, r.Data.Yesterday.Fl)
    fmt.Println("天氣:", r.Data.Yesterday.Type)
    fmt.Println("溫馨提示:", r.Data.Yesterday.Notice)
  } else if day == "預(yù)測(cè)" {
    fmt.Println("====================================")
    for _, item := range r.Data.Forecast {
      fmt.Println("日期:", item.Date)
      fmt.Println("溫度:", item.Low, item.High)
      fmt.Println("風(fēng)量:", item.Fx, item.Fl)
      fmt.Println("天氣:", item.Type)
      fmt.Println("溫馨提示:", item.Notice)
      fmt.Println("====================================")
    }
  } else {
    fmt.Println("...")
  }

}
func Requests(url string) (string, error) {
  response, err := http.Get(url)
  if err != nil {
    return "", err
  }
  defer response.Body.Close()
  body, _ := ioutil.ReadAll(response.Body)
  return string(body), nil
}

最終的效果大概如下:

./weather -c 上海

城市: 上海
濕度: 80%
空氣質(zhì)量: 輕度污染
溫馨提示: 兒童、老年人及心臟、呼吸系統(tǒng)疾病患者人群應(yīng)減少長(zhǎng)時(shí)間或高強(qiáng)度戶外鍛煉


================================
./weaather -c 上海 -d 昨天

城市: 上海
日期: 28日星期二
溫度: 低溫 12.0℃ 高溫 19.0℃
風(fēng)量: 西南風(fēng) <3級(jí)
天氣: 小雨
溫馨提示: 霧蒙蒙的雨天,最喜歡一個(gè)人聽(tīng)音樂(lè)

以上就是“Go語(yǔ)言中怎么讀取命令參數(shù)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI