还不会命令行?用Go Flag自写命令行程序
时间:2022-07-22
本文章向大家介绍还不会命令行?用Go Flag自写命令行程序,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
作者 | 陌无崖
转载请联系授权
内容目录
Go flag包详解前言入门案例源码包解析定义flag参数完整案例
前言
相信大家都用到过命令行工具。尤其当我们在用Linux进行代码开发时,会使用很多工具,比如下面的这张图。那么自己如何开发一个命令行工具呢?
image.png
入门案例
在这个案例中我们需要用到Go官方包中的flag解析包。新建一个flag.go
package main
import (
"flag"
"fmt"
)
// 定义命令行参数对应的变量,这三个变量都是指针类型
var cliName = flag.String("name", "nick", "Input Your Name")
var cliAge = flag.Int("age", 28, "Input Your Age")
var cliGender = flag.String("gender", "male", "Input Your Gender")
// 定义一个值类型的命令行参数变量,在 Init() 函数中对其初始化
// 因此,命令行参数对应变量的定义和初始化是可以分开的
var cliFlag int
func Init() {
flag.IntVar(&cliFlag, "flagname", 1234, "Just for demo")
}
func main() {
// 初始化变量 cliFlag
Init()
// 把用户传递的命令行参数解析为对应变量的值
flag.Parse()
// flag.Args() 函数返回没有被解析的命令行参数
// func NArg() 函数返回没有被解析的命令行参数的个数
fmt.Printf("args=%s, num=%dn", flag.Args(), flag.NArg())
for i := 0; i != flag.NArg(); i++ {
fmt.Printf("arg[%d]=%sn", i, flag.Arg(i))
}
// 输出命令行参数
fmt.Println("name=", *cliName)
fmt.Println("age=", *cliAge)
fmt.Println("gender=", *cliGender)
fmt.Println("flagname=", cliFlag)
}
编译我们的源文件为二进制
go build .flag.go
测试以下
.flag.exe help
image.png
.flag.exe -name yuwei
image.png
源码包解析
定义flag参数
1、通过flag.Xxx()
。Xxx可以指String、Bool、Int等基本数据类型。使用这种方式会相应的返回一个指针。如:
// 定义命令行参数对应的变量,这三个变量都是指针类型
var cliName = flag.String("name", "nick", "Input Your Name")
var cliAge = flag.Int("age", 28, "Input Your Age")
var cliGender = flag.String("gender", "male", "Input Your Gender")
函数中的参数分别代表的含义为:命令行参数、参数的默认值、参数的提示或者解释。
2、通过flag.XxxVar()
方法将flag绑定到一个变量,该种方式返回值类型,如:
var cliFlag int
var flag.IntVar(&cliFlag, "flagname", 1234, "Just for demo")
函数中的参数分别代表的含义为:待赋值的变量、命令行参数、参数的默认值、参数的提示或者解释。
3、通过flag.Var()
绑定自定义类型,自定义类型需要实现Value接口(Receives必须为指针),如下案例
- 新建一个type.go
type self struct {
Address string
Area string
}
func (s *self) String() string {
return fmt.Sprintf("%s", *s)
}
func (s *self) Set(value string) error {
return nil
}
- 定义参数
var selfFlag self
var flag.Var(&selfFlag, "self", "please input address,area eg: "beijing china"")
这里需要注意的是实现接口Value中函数String()代表定义默认值。Set()函数是对参数值的接收对其进行操作。
完整案例
main.go
package main
import (
"flag"
"fmt"
)
// 定义命令行参数对应的变量,这三个变量都是指针类型
var cliName = flag.String("name", "nick", "Input Your Name")
var cliAge = flag.Int("age", 28, "Input Your Age")
var cliGender = flag.String("gender", "male", "Input Your Gender")
// 定义一个值类型的命令行参数变量,在 Init() 函数中对其初始化
// 因此,命令行参数对应变量的定义和初始化是可以分开的
var cliFlag int
var selfFlag self
func Init() {
flag.IntVar(&cliFlag, "flagname", 1234, "Just for demo")
flag.Var(&selfFlag, "self", "please input address,area eg: "beijing china"")
}
func main() {
// 初始化变量 cliFlag
Init()
// 把用户传递的命令行参数解析为对应变量的值
flag.Parse()
// flag.Args() 函数返回没有被解析的命令行参数
// func NArg() 函数返回没有被解析的命令行参数的个数
fmt.Printf("args=%s, num=%dn", flag.Args(), flag.NArg())
for i := 0; i != flag.NArg(); i++ {
fmt.Printf("arg[%d]=%sn", i, flag.Arg(i))
}
// 输出命令行参数
fmt.Println("name=", *cliName)
fmt.Println("age=", *cliAge)
fmt.Println("gender=", *cliGender)
fmt.Println("flagname=", cliFlag)
fmt.Println("selfFlag=", selfFlag)
}
type.go
/*
* @Author: your name
* @Date: 2019-11-22 15:38:48
* @LastEditTime: 2019-11-22 19:19:56
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: GoWebd:praticetflagdemotype.go
*/
package main
import "fmt"
import "errors"
import "strings"
type self struct {
Address string
Area string
}
func (s *self) String() string {
*s = self{"Beingjing", "China"}
return fmt.Sprintf("%s", *s)
}
func (s *self) Set(value string) error {
if len(value) <= 0 {
return errors.New("参数为空,请输入正确的参数")
}
data := strings.Split(value, " ")
*s = self{
data[0],
data[1],
}
fmt.Println(*s)
return nil
}
运行我们程序
image.png
image.png
- Ubuntu 安装 JDK8 的两种方式
- git命令-切换分支
- 如何让dedecms文章点击量增加一定的数值
- dedecms自增标签[field:global.autoindex/]的运用
- dedecms调用副栏目文章怎么操作
- 12个非常有用的JavaScript技巧
- 使用JPA中@Query 注解实现update 操作
- 配合dedecms内容模型实现后台输入栏目id前端输出文章列表
- SpringBoot之前端文件管理
- Spring Boot 设置静态资源访问
- IDEA更换主题
- 用正则表达式给字符串属性值都加上双引号
- Spring Boot修改启动端口
- Packet for query is too large (12238 > 1024). You can change this value
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法