欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go語(yǔ)言中讀取命令參數(shù)的幾種方法總結(jié)

 更新時(shí)間:2017年11月30日 09:53:44   作者:謝小路  
部署golang項(xiàng)目時(shí)難免要通過命令行來設(shè)置一些參數(shù),那么在golang中如何操作命令行參數(shù)呢?那么下面這篇文章就來給大家介紹了關(guān)于Go語(yǔ)言中讀取命令參數(shù)的幾種方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起看看吧。

前言

對(duì)于一名初學(xué)者來說,想要盡快熟悉 Go 語(yǔ)言特性,所以以操作式的學(xué)習(xí)方法為主,比如編寫一個(gè)簡(jiǎn)單的數(shù)學(xué)計(jì)算器,讀取命令行參數(shù),進(jìn)行數(shù)學(xué)運(yùn)算。

本文講述使用三種方式講述 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ù),一般解析出來都是一個(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() 來解析命令行參數(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)值,以及別名(縮寫)

那么在這個(gè)框架中如何實(shí)現(xiàn)參數(shù)的操作呢:主要是重寫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)算,然后編寫相應(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)查詢單詞的功能。

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

不一一列了。

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

GO 如何進(jìn)行 HTTP 訪問??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è)人聽音樂

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • Go 熱加載之fresh詳解

    Go 熱加載之fresh詳解

    這篇文章主要為大家介紹了Go 熱加載之fresh詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • GO語(yǔ)言中常見的排序算法使用示例

    GO語(yǔ)言中常見的排序算法使用示例

    這篇文章主要為大家介紹了GO語(yǔ)言中常見排序算法的使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • 淺談Golang的new與make區(qū)別是什么

    淺談Golang的new與make區(qū)別是什么

    本文主要介紹了Golang的new與make區(qū)別是什么,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Go空結(jié)構(gòu)體struct{}的作用是什么

    Go空結(jié)構(gòu)體struct{}的作用是什么

    本文主要介紹了Go空結(jié)構(gòu)體struct{}的作用是什么,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Go語(yǔ)言從單體服務(wù)到微服務(wù)設(shè)計(jì)方案詳解

    Go語(yǔ)言從單體服務(wù)到微服務(wù)設(shè)計(jì)方案詳解

    這篇文章主要為大家介紹了Go語(yǔ)言從單體服務(wù)到微服務(wù)設(shè)計(jì)方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • GoLang中拼接字符串性能優(yōu)化方法詳解

    GoLang中拼接字符串性能優(yōu)化方法詳解

    最近在做性能優(yōu)化,有個(gè)函數(shù)里面的耗時(shí)特別長(zhǎng),看里面的操作大多是一些字符串拼接的操作,而字符串拼接在 golang 里面其實(shí)有很多種實(shí)現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Golang語(yǔ)言如何高效拼接字符串的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • golang?RPC包原理和使用詳細(xì)介紹

    golang?RPC包原理和使用詳細(xì)介紹

    golang的rpc支持三個(gè)級(jí)別的RPC:TCP、HTTP、JSONRPC。但Go的RPC包是獨(dú)一無二的RPC,它和傳統(tǒng)的RPC系統(tǒng)不同,它只支持Go開發(fā)的服務(wù)器與客戶端之間的交互,因?yàn)樵趦?nèi)部,它們采用了Gob來編碼
    2022-09-09
  • 詳解Golang如何實(shí)現(xiàn)一個(gè)環(huán)形緩沖器

    詳解Golang如何實(shí)現(xiàn)一個(gè)環(huán)形緩沖器

    環(huán)形緩沖器(ringr?buffer)是一種用于表示一個(gè)固定尺寸、頭尾相連的緩沖區(qū)的數(shù)據(jù)結(jié)構(gòu),適合緩存數(shù)據(jù)流。本文將利用Golang實(shí)現(xiàn)一個(gè)環(huán)形緩沖器,需要的可以參考一下
    2022-09-09
  • golang執(zhí)行命令獲取執(zhí)行結(jié)果狀態(tài)(推薦)

    golang執(zhí)行命令獲取執(zhí)行結(jié)果狀態(tài)(推薦)

    這篇文章主要介紹了golang執(zhí)行命令獲取執(zhí)行結(jié)果狀態(tài)的相關(guān)知識(shí),非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2019-11-11
  • Go語(yǔ)言中的基礎(chǔ)數(shù)據(jù)類型使用實(shí)例

    Go語(yǔ)言中的基礎(chǔ)數(shù)據(jù)類型使用實(shí)例

    這篇文章主要為大家介紹了Go中的基礎(chǔ)數(shù)據(jù)類型使用示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04

最新評(píng)論