Summary of several methods for reading command parameters in Go language

  • 2020-06-12 09:20:08
  • OfStack

preface

For a beginner, he wants to get familiar with the features of Go language as soon as possible, so he focuses on operational learning methods, such as writing a simple mathematical calculator, reading command-line parameters and performing mathematical operations.

This article describes three ways to tell how the Go language takes command-line arguments and performs a simple mathematical calculation. For demonstration purposes, the final command line result looks like this:


# input 
./calc add 1 2
# output
3

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

# input
./calc mul 10 20
# out
200

The three ways to use it are:

The built-in os package reads the command parameters The built-in flag package reads the command parameters The cli framework reads the command parameters

0. Historical experience

If you are familiar with Python and Shell scripts, you can compare:

Python


import sys

args = sys.argv

# args  is 1 A list of 
#  The first 1 The value of theta is theta   The file name 
#  In addition to the first 1 The other values are the accepted parameters 

Shell


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

echo $name
echo $age
# `$0`  Representation file name 
# `$1`  According to the first 1 A parameter 
# `$2`  According to the first 2 A parameter 

The first element represents the file name, and the remaining parameters represent the received parameters.

Ok, so to do "simple math", read the command-line arguments: for example./calc add 1 and 2

The first element other than the filename resolves to an operation that performs a mathematical operation, such as add, sub, mul, sqrt
The remaining parameters represent the value of the operation

Note: Command-line reading parameters 1 are usually strings, and numeric calculations require data type conversion

So that's the idea.

1. OS gets the command-line arguments


os.Args

#  Is the accepted parameter, is 1 A slice 

strconv.Atoi 

#  Converts a string value to an integer 

strconv.Itoa

#  Converts an integer to a string 

strconv.ParseFloat

#  Converts a string value to a floating point value 

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
}

The end result is something like:


./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 gets command-line arguments

The flag package is easier to read than the os package. You can customize the types of parameters passed in: string, integer, floating point, default parameter Settings, etc

The basic usage is as follows:


var operate string

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

# explain

Bind operate variable, name="o", value="add", usage="operation for calc"

You can also define them as pointer variables


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

You can also customize the flag type

After all variables have been registered, call flag.Parse () to resolve the command-line arguments. If you bind variables, use variables directly.
If pointer variable type is used, you need to use *operate like this.

flag. Args() represents the set of all command line arguments received and is also 1 slice


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
}

The final results are as follows:


import sys

args = sys.argv

# args  is 1 A list of 
#  The first 1 The value of theta is theta   The file name 
#  In addition to the first 1 The other values are the accepted parameters 
0

3. CLI framework

cli is one of the most popular command-line frameworks in the industry.

So you first need to install:


import sys

args = sys.argv

# args  is 1 A list of 
#  The first 1 The value of theta is theta   The file name 
#  In addition to the first 1 The other values are the accepted parameters 
1

import sys

args = sys.argv

# args  is 1 A list of 
#  The first 1 The value of theta is theta   The file name 
#  In addition to the first 1 The other values are the accepted parameters 
2

Ok, so how do we do this for simple math?

It mainly USES Flag function in the framework to set the parameters


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",
 },
}

As you can see, we used three parameters: operation, numberone, and numbertwo

It also defines the type of the parameter, the default value, and the alias (abbreviation)

So how do you implement parameter manipulation in this framework: essentially overriding the ES126en.Action method


import sys

args = sys.argv

# args  is 1 A list of 
#  The first 1 The value of theta is theta   The file name 
#  In addition to the first 1 The other values are the accepted parameters 
4

import sys

args = sys.argv

# args  is 1 A list of 
#  The first 1 The value of theta is theta   The file name 
#  In addition to the first 1 The other values are the accepted parameters 
5

The end result of calling this function is as follows:


import sys

args = sys.argv

# args  is 1 A list of 
#  The first 1 The value of theta is theta   The file name 
#  In addition to the first 1 The other values are the accepted parameters 
6

4 other

If you know how to read command-line arguments, you can do something even more interesting.

For example, there are many free API interfaces on the Internet, such as API for weather and lunar calendar queries.

There are also 1 query interface, such as youdao cloud translation interface, you can achieve the function of translation.

Or scallop interface, to achieve the function of query words.

For example, 1 some music interface, music information query.

No more columns 11.

The following implementation of a call to the free query weather interface implementation command line query weather.

How do HTTP access HTTP? The built-in net/http can be implemented

A simple GET operation is as follows:


import sys

args = sys.argv

# args  is 1 A list of 
#  The first 1 The value of theta is theta   The file name 
#  In addition to the first 1 The other values are the accepted parameters 
7

Free API URL:


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

The result is 1 Json data


import sys

args = sys.argv

# args  is 1 A list of 
#  The first 1 The value of theta is theta   The file name 
#  In addition to the first 1 The other values are the accepted parameters 
9

So our task is to pass in the name of the "city" and parse the returned Json data.


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 = " Weather forecast applet "

  app.Flags = []cli.Flag{
    cli.StringFlag{
      Name: "city, c",
      Value: " Shanghai ",
      Usage: " City Chinese name ",
    },
    cli.StringFlag{
      Name: "day, d",
      Value: " Today, ",
      Usage: " optional :  Today, ,  Yesterday, ,  To predict ",
    },
    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(" For the weather API There is an error , %s", r.Message)
      return nil
    }
    Print(day, r)
    return nil
  }
  app.Run(os.Args)

}


func Print(day string, r Response) {
  fmt.Println(" city :", r.CityName)
  if day == " Today, " {
    fmt.Println(" humidity :", r.Data.ShiDu)
    fmt.Println(" Air quality :", r.Data.Quality)
    fmt.Println(" Warm prompt :", r.Data.Ganmao)
  } else if day == " Yesterday, " {
    fmt.Println(" The date of :", r.Data.Yesterday.Date)
    fmt.Println(" The temperature :", r.Data.Yesterday.Low, r.Data.Yesterday.High)
    fmt.Println(" Air volume :", r.Data.Yesterday.Fx, r.Data.Yesterday.Fl)
    fmt.Println(" The weather :", r.Data.Yesterday.Type)
    fmt.Println(" Warm prompt :", r.Data.Yesterday.Notice)
  } else if day == " To predict " {
    fmt.Println("====================================")
    for _, item := range r.Data.Forecast {
      fmt.Println(" The date of :", item.Date)
      fmt.Println(" The temperature :", item.Low, item.High)
      fmt.Println(" Air volume :", item.Fx, item.Fl)
      fmt.Println(" The weather :", item.Type)
      fmt.Println(" Warm prompt :", 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
}

The final effect is as follows:


./weather -c  Shanghai 

 city :  Shanghai 
 humidity : 80%
 Air quality :  Light pollution 
 Warm prompt :  Children, the elderly and people with heart and respiratory diseases should reduce long or high intensity outdoor exercise 


================================
./weaather -c  Shanghai  -d  Yesterday, 

 city :  Shanghai 
 The date of : 28 Day of week 2
 The temperature :  The low temperature  12.0 ℃   The high temperature  19.0 ℃ 
 Air volume :  Southwest winds  <3 level 
 The weather :  Light rain 
 Warm prompt :  Misty rainy days, favorite 1 Personal Listening to music 

conclusion


Related articles: