- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Go语言中读取命令参数的几种方法总结由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
对于一名初学者来说,想要尽快熟悉 Go 语言特性,所以以操作式的学习方法为主,比如编写一个简单的数学计算器,读取命令行参数,进行数学运算.
本文讲述使用三种方式讲述 Go 语言如何接受命令行参数,并完成一个简单的数学计算,为演示方便,最后的命令行结果大概是这样的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# input
./calc add 1 2
# output
3
# input
./calc sub 1 2
# out
-1
# input
./calc mul 10 20
# out
200
|
使用的三种方式是:
0. 已有历史经验 。
如果你熟悉 Python 、Shell 脚本,你可以比较下:
Python 。
1
2
3
4
5
6
7
|
import
sys
args
=
sys.argv
# args 是一个列表
# 第一个值表示的是 文件名
# 除第一个之外,其他的值是接受的参数
|
Shell 。
1
2
3
4
5
6
7
8
9
10
11
12
|
if
[ $
# -ne 2 ]; then
echo
"Usage: $0 param1 pram2"
exit
1
fi
name=$1
age=$2
echo
$name
echo
$age
# `$0` 表示文件名
# `$1` 表示第一个参数
# `$2` 表示第二个参数
|
能看出一些共性,接收参数,一般解析出来都是一个数组(列表、切片), 第一个元素表示的是文件名,剩余的参数表示接收的参数.
好,那么为了实现 “简单数学计算” 这个功能,读取命令行参数:比如 ./calc add 1 2 。
除文件名之外的第一个元素:解析为 进行数学运算的 操作,比如: add、sub、mul、sqrt 其余参数表示:进行操作的数值 。
注意:命令行读取的参数一般为字符串,进行数值计算需要进行数据类型转换 。
大概思路就是这样.
1. OS 获取命令行参数 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
os.Args
# 为接受的参数,是一个切片
strconv.Atoi
# 将字符串数值转换为整型
strconv.Itoa
# 将整型转换为字符串
strconv.ParseFloat
# 将字符串数值转换为浮点型
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
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
}
|
最后的效果大概是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
./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 获取命令行参数 。
flag 包比 os 读取参数更方便。可以自定义传入的参数的类型:比如字符串,整型,浮点型,默认参数设置等 。
基本的使用方法如下:
1
2
3
|
var operate string
flag.StringVar(&operate,"o", "add", "operation for calc")
|
# 解释 。
绑定 operate 变量, name="o", value="add" , usage="operation for calc" 。
也可以这样定义为指针变量 。
1
|
var operate := flag.String("o", "add", "operation for calc")
|
同时还可以自定义 flag 类型 。
所有变量注册之后,调用 flag.Parse() 来解析命令行参数, 如果是绑定变量的方式,直接使用变量进行操作, 如果使用指针变量型,需要 *operate 这样使用.
flag.Args() 表示接收的所有命令行参数集, 也是一个切片 。
1
2
3
|
for index, value := range flag.Args {
fmt.Println(index, value)
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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
}
|
最后的结果效果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
./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 是一款业界比较流行的命令行框架.
所以你首先需要安装:
1
|
go get github.com/urfave/cli
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 一个简单的示例如下:
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)
}
|
好,为实现 “简单数学计算” 的功能,我们应该怎么实现呢?
主要是 使用 框架中的 Flag 功能,对参数进行设置 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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",
},
}
|
能看出,我们使用了三个参数:operation、numberone、numbertwo 。
同时定义了参数的类型,默认值,以及别名(缩写) 。
那么在这个框架中如何实现参数的操作呢:主要是重写app.Action 方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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
}
# 对 operation 参数进行判断,执行的是那种运算,然后编写相应的运算操作
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
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)
}
|
调用这个函数的最终效果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
./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 其他 。
知道如何读取命令行参数,就可以实现一些更有意思的事.
比如网上有许多免费的 API 接口,比如查询天气,查询农历的API 接口.
还有一些查询接口,比如有道云翻译接口,你可以实现翻译的功能.
或者扇贝的接口,实现查询单词的功能.
再比如一些音乐接口,实现音乐信息查询.
不一一列了.
下面实现一个调用免费的查询天气的接口实现命令行查询天气.
GO 如何进行 HTTP 访问?内置的 net/http 可以实现 。
一个简易的GET 操作如下:
1
2
3
4
5
6
7
8
9
|
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
}
|
免费的 API URL 如下:
1
|
http://www.sojson.com/open/api/weather/json.shtml?city=北京
|
返回的结果是一个Json 格式的数据 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
{
"status": 200,
"data": {
"wendu": "29",
"ganmao": "各项气象条件适宜,发生感冒机率较低。但请避免长期处于空调房间中,以防感冒。",
"forecast": [
{
"fengxiang": "南风",
"fengli": "3-4级",
"high": "高温 32℃",
"type": "多云",
"low": "低温 17℃",
"date": "16日星期二"
},
{
"fengxiang": "南风",
"fengli": "微风级",
"high": "高温 34℃",
"type": "晴",
"low": "低温 19℃",
"date": "17日星期三"
},
{
"fengxiang": "南风",
"fengli": "微风级",
"high": "高温 35℃",
"type": "晴",
"low": "低温 22℃",
"date": "18日星期四"
},
{
"fengxiang": "南风",
"fengli": "微风级",
"high": "高温 35℃",
"type": "多云",
"low": "低温 22℃",
"date": "19日星期五"
},
{
"fengxiang": "南风",
"fengli": "3-4级",
"high": "高温 34℃",
"type": "晴",
"low": "低温 21℃",
"date": "20日星期六"
}
],
"yesterday": {
"fl": "微风",
"fx": "南风",
"high": "高温 28℃",
"type": "晴",
"low": "低温 15℃",
"date": "15日星期一"
},
"aqi": "72",
"city": "北京"
},
"message": "OK"
}
|
所以我们的任务就是传入 “城市” 的名称,再对返回的 Json 数据解析.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
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 = "天气预报小程序"
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "city, c",
Value: "上海",
Usage: "城市中文名",
},
cli.StringFlag{
Name: "day, d",
Value: "今天",
Usage: "可选: 今天, 昨天, 预测",
},
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出现错误, %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("空气质量:", 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("风量:", r.Data.Yesterday.Fx, r.Data.Yesterday.Fl)
fmt.Println("天气:", r.Data.Yesterday.Type)
fmt.Println("温馨提示:", r.Data.Yesterday.Notice)
} else if day == "预测" {
fmt.Println("====================================")
for _, item := range r.Data.Forecast {
fmt.Println("日期:", item.Date)
fmt.Println("温度:", item.Low, item.High)
fmt.Println("风量:", 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
}
|
最终的效果大概如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
./weather -c 上海
城市: 上海
湿度: 80%
空气质量: 轻度污染
温馨提示: 儿童、老年人及心脏、呼吸系统疾病患者人群应减少长时间或高强度户外锻炼
================================
./weaather -c 上海 -d 昨天
城市: 上海
日期: 28日星期二
温度: 低温 12.0℃ 高温 19.0℃
风量: 西南风 <3级
天气: 小雨
温馨提示: 雾蒙蒙的雨天,最喜欢一个人听音乐
|
总结 。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我的支持.
原文链接:http://www.jianshu.com/p/548adff0d10d 。
最后此篇关于Go语言中读取命令参数的几种方法总结的文章就讲到这里了,如果你想了解更多关于Go语言中读取命令参数的几种方法总结的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
1、定义 设 \(u\) 和 \(v\) 为一张图上的任意两个节点。令 \(c(u, v)\) 为它们之间的边的容量, \(f(u, v)\) 为它们之间的流量,则需要满足以
1、前言 工作中涉及到文件系统,有时候需要判断文件和目录是否存在。我结合apue第四章文件和目录,总结一下如何正确判断文件和目录是否存在,方便以后查询。 2、stat系列函数 stat函数用来
并查集(Union-Find Set): 一种用于管理分组的数据结构。它具备两个操作:(1)查询元素a和元素b是否为同一组 (2) 将元素a和b合并为同一组。 注意:并查集不能将在同一组的元素拆
当下,注解非常流行,以前很长篇的代码,现在基本上一个注解就能搞定。 那,在Mybatis中又有哪些注解呢? Mybatis中的注解基本上都在org.apache.ibatis.annotat
指针操作数组,方法一是p+index,方法二是p[index],第二种方法跟数组访问方法是一样的。 数组引用返回的是数组的第一个元素的指针地址。 可以将指针指向数组的任意元素,然后从那里开始访问
通常部署完php环境后会进行一些安全设置,除了熟悉各种php漏洞外,还可以通过配置php.ini来加固PHP的运行环境,PHP官方也曾经多次修改php.ini的默认设置。 下面对php.ini中一
在JavaScript中,使用typeof可以检测基本数据类型,使用instanceof可以检测引用数据类型。在PHP中,也有检测数据类型的方法,具体如下: 1、输出变量的数据类型(gettype
把图片缓存到本地,在很多场景都会用到,如果只是存储文件信息,那建一个plist文件,或者数据库就能很方便的解决问题,但是如果存储图片到沙盒就没那么方便了。这里简单介绍两种保存图片到沙盒的方法。
(1)需要安装docker容器,在docker容器内安装jenkins,gogs,tomcat。 新建maven项目,添加findbugs plugin。 使用docker
今天主题是实现并发服务器,实现方法有多种版本,先从简单的单进程代码实现到多进程,多线程的实现,最终引入一些高级模块来实现并发TCP服务器。 说到TCP,想起吐槽大会有个段子提到三次握手,也只有程序
如下所示: Ctrl+1或F2快速修复 Ctrl+D快捷删除行 Shift+Enter 快速切换到下一行,在本行的任何位置都可 Ctrl+F11快速运行代码 Alt+上下键 快速移动行(可
JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。 JSP编译后是”类servlet”。 Servlet和JSP最主要的不同点在于,Servlet的应用逻辑
Java中的Runable,Callable,Future,FutureTask,ExecutorService,Excetor,Excutors,ThreadPoolExcetor在这里对这些关键
读取Java文件到byte数组的三种方法(总结) ? 1
用java实现的数组创建二叉树以及递归先序遍历,递归中序遍历,递归后序遍历,非递归前序遍历,非递归中序遍历,非递归后序遍历,深度优先遍历,广度优先遍历8种遍历方式:
1、简明总结 ASCII(char) 返回字符的ASCII码值 BIT_LENGTH(str) 返回字符串的比特长度 CONCAT(s1,s2…,sn)
java应用服务器(web server),是指运行java程序的web应用服务器软件,不包括nginx、Apache等通用web服务器软件。 一、Tomcat Tomcat是Apache 软件基
事务作为抽象层,允许应用忽略DB 内部一些复杂并发问题和某些硬件、软件故障,简化应用层的处理逻辑:事务中止(transaction abort),而应用仅需重试。对复杂访问模式,事务可大大减少需要考虑
我们在本教程学习了如何描述 XML 文档的结构 我们学习到了如何使用 DTD 来定义一个 XML 文档的合法元素,以及如何在我们的 XML 内部或者作为一个外部引用来声明 DTD 我们学习了如何为
在这个XPath 基础教程中我们讲解了如何在 XML 文档中查找信息 我们可以使用 XPath 的元素和属性在 XML 文档中进行导航 我们也学习了如何使用 XPath 中内建的某些标准函数 如
我是一名优秀的程序员,十分优秀!