055-实战 flag.Value 接口

如果你中间是跳跃着看的,希望你一定不要错过《参数解析》 一文。

我们已经学习过参数解析的 flag 包相关使用方法,所以这里不会再赘述,如果你还不会,建议你回去学习并掌握它。

1. 简单回顾

很久以前,我们就学习过 flag 包的使用方法,它可以解析常见的基础类型,比如 int, string 等。 flag 包使用起来非常简单,只要使用相关的方法,将要解析的标志加入到标志集合,最后调用 flag.Parse 就可以完成解析。下面是解析 int 类型的例子:

var age int
flag.IntVar(&age, "a", 15, "设置年龄") // 添加标志集合
flag.Parse() // 解析

2. flag.Value 接口

flag 包固然好用,但是默认情况下它只支持解析基础数据类型。有时候我们想解析用户自定义的类型怎么办?

在 Go 里,一切都好说。有了接口,这件事情就好办。只要你定义的类型实现了 flag.Value 接口,就可以使用 flag.Var 函数添加标志集合了。flag.Value 接口定义如下:

type Value interface {
    String() string
    Set(string) error
}

一旦你的类型实现了 String 方法和 Set 方法,你就可以调用 flag.Var 来解析你的专属类型了。来看一个具体实例。

3. 示例

下面是自定义的一个 Person 类型,有两个成员,一个 Name,一个 Age.

type Person struct {
    Name string
    Age  int
}

我们希望通过命令行参数来指定 Person 对象的值。比如我们希望输入以下命令,就能从命令行传递一个 Person 对象的参数了。

$ ./demo -p allen 19

在此之前,我们先实现 flag.Value 接口。

  • 实现 flag.Value 接口
// 实现 flag.Value 接口
func (p *Person) Set(s string) error {
    var name string
    var age int
    // Sscanf 对字符串 s 解析,提取出 name 和 age 并赋值给接收器对象。
    _, err := fmt.Sscanf(s, "%s %d", &name, &age)
    *p = Person{name, age}
    return err
}

func (p *Person) String() string {
    return fmt.Sprintf("name:%s age:%d", p.Name, p.Age)
}
  • 使用 flag.Var 解析
func main() {
    var p Person
    flag.Var(&p, "p", "设置 person") // 添加标志集合 p
    flag.Parse() // 解析命令行参数
    fmt.Printf("%v\n", &p) // 只有 *Person 实现了 String 方法,所以需要传递 &p
}

运行程序,结果如下:

$ go run demo.go -p "allen 19"
name:allen age:19

4. 总结

  • 掌握 flag.Value 接口
  • 掌握实现接口的方法
  • 理解接口的用处

通过对 flag.Value 的学习,你就能认识到接口的妙用了吧。从命令行解析参数本来就是一件重复性的劳动,你当然也可以手工去解析,不过自己实现一套参数解析功能的函数,这完全和 flag 包的功能重复,实在没有必要。

flag 包用更加智慧的办法解决了用户自定义类型的解析——使用接口。即便 flag 不知道你的类型长什么样也没关系,只要你的类型支持了 String 和 Set 这样的行为就够了。本质上这就是一种协议,一种约定。

好的,以下是详细的步骤: 1. 打开右侧的命令行界面,输入以下命令进入 `/data/workspace/myshixun` 目录: ``` cd /data/workspace/myshixun ``` 2. 加密文件:输入以下命令进行加密,将 `flag` 文件加密成 `flag.tar.gz` 文件: ``` tar -czvf - flag | openssl des3 -salt -k admin123 -out flag.tar.gz ``` 解释一下这个命令: - `tar -czvf - flag`:将 `flag` 文件打包成 `tar` 格式,并输出到标准输出流(即屏幕上)。 - `|`:管道符,将前一个命令的输出作为后一个命令的输入。 - `openssl des3 -salt -k admin123 -out flag.tar.gz`:对输入的内容进行 `3DES` 加密,并输出到 `flag.tar.gz` 文件中。 3. 查看加密后的文件:输入以下命令查看一下加密后的文件: ``` ls -l flag.tar.gz ``` 4. 解密文件:输入以下命令进行解密,将 `flag.tar.gz` 文件解密成 `flag` 文件: ``` openssl des3 -d -k admin123 -salt -in flag.tar.gz | tar xzf - ``` 解释一下这个命令: - `openssl des3 -d -k admin123 -salt -in flag.tar.gz`:对 `flag.tar.gz` 文件进行 `3DES` 解密,并输出到标准输出流(即屏幕上)。 - `|`:管道符,将前一个命令的输出作为后一个命令的输入。 - `tar xzf -`:将标准输入流中的内容解压缩,并输出到当前目录下。 5. 查看解密后的文件:输入以下命令查看一下解密后的文件: ``` ls -l flag ``` 6. 将解密结果输出到 IDE 环境中:输入以下命令将解密后的结果输出到标准输出流中: ``` cat flag ``` 复制标准输出流中的内容,粘贴到 IDE 环境中进行测评。 希望这些详细的步骤可以帮助到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值