前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >还不会命令行?用Go Flag自写命令行程序

还不会命令行?用Go Flag自写命令行程序

作者头像
陌无崖
发布2020-07-27 11:10:30
9670
发布2020-07-27 11:10:30
举报

作者 | 陌无崖

转载请联系授权

内容目录

Go flag包详解前言入门案例源码包解析定义flag参数完整案例

前言

相信大家都用到过命令行工具。尤其当我们在用Linux进行代码开发时,会使用很多工具,比如下面的这张图。那么自己如何开发一个命令行工具呢?

image.png

入门案例

在这个案例中我们需要用到Go官方包中的flag解析包。新建一个flag.go

代码语言:javascript
复制
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=%d\n", flag.Args(), flag.NArg())
    for i := 0; i != flag.NArg(); i++ {
        fmt.Printf("arg[%d]=%s\n", i, flag.Arg(i))
    }

    // 输出命令行参数
    fmt.Println("name=", *cliName)
    fmt.Println("age=", *cliAge)
    fmt.Println("gender=", *cliGender)
    fmt.Println("flagname=", cliFlag)
}

编译我们的源文件为二进制

代码语言:javascript
复制
 go build .\flag.go

测试以下

代码语言:javascript
复制
.\flag.exe help

image.png

代码语言:javascript
复制
 .\flag.exe -name yuwei 

image.png

源码包解析

定义flag参数

1、通过flag.Xxx()。Xxx可以指String、Bool、Int等基本数据类型。使用这种方式会相应的返回一个指针。如:

代码语言:javascript
复制
// 定义命令行参数对应的变量,这三个变量都是指针类型
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绑定到一个变量,该种方式返回值类型,如:

代码语言:javascript
复制
var cliFlag int
var flag.IntVar(&cliFlag, "flagname", 1234, "Just for demo")

函数中的参数分别代表的含义为:待赋值的变量、命令行参数、参数的默认值、参数的提示或者解释。

3、通过flag.Var()绑定自定义类型,自定义类型需要实现Value接口(Receives必须为指针),如下案例

  • 新建一个type.go
代码语言:javascript
复制
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
}
  • 定义参数
代码语言:javascript
复制
var selfFlag self
var flag.Var(&selfFlag, "self", "please input address,area eg: \"beijing china\"")

这里需要注意的是实现接口Value中函数String()代表定义默认值。Set()函数是对参数值的接收对其进行操作。

完整案例

main.go

代码语言:javascript
复制
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=%d\n", flag.Args(), flag.NArg())
    for i := 0; i != flag.NArg(); i++ {
        fmt.Printf("arg[%d]=%s\n", 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

代码语言:javascript
复制
/*
 * @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:\pratice\tflag\demo\type.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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 golang技术杂文 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 内容目录
  • 前言
  • 入门案例
  • 源码包解析
    • 定义flag参数
      • 完整案例
      相关产品与服务
      命令行工具
      腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档