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 parameters0. 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