Golang 的 cobra 是如何实现使用链表实现命令树的

文章详细介绍了Golang的Cobra库如何使用链表结构实现命令树,每个命令作为独立节点,通过parent.AddCommand()方法建立父子关系。Cobra的Command结构体包含子命令和父命令指针,通过AddCommand方法添加子命令并设置父命令,实现命令的组合和多级嵌套。同时,文章指出由于使用指针,一个命令可以属于多个父命令,形成灵活的命令树结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Golang 的 cobra 是如何实现使用链表实现命令树的

在 cobra 中, 每个 命令 都是独立的。 通过 parent.AddCommand(children) 的形式进行串连。

var root = &cobra.Command{}

var child = &cobra.Command{}

func init() {
    root.AddCommand(child)
}

没了, 应用上就这么多。

cobra 命令树

如果你用过 gin 的路由树的话, 可能会对 cobra 的命令树实现更为深刻。

删除多余的结构, cobra 节点 就是下面这样的。

type Command struct {
    // 子命令
    commands []*Command
    // 父命令
    parent *Command
}

当进行 命令树 组合的时候, 是通过 领养/挂靠 的方式实现的。

// AddCommand adds one or more commands to this parent command.
func (c *Command) AddCommand(cmds ...*Command) {
    for i, x := range cmds {
        if cmds[i] == c {
            panic("Command can't be a child of itself")
        }

        // 为子命令设置父命令(认亲)
        cmds[i].parent = c // (1)
// 省略
        // 添加传入的子命令
        c.commands = append(c.commands, x) // (2)
    }
}

(1) 在我们可以在任意节点调用 Execute 方法, 这个调用会通过 递归 找到最上层的 节点。

func (c *Command) Execute() error {
    _, err := c.ExecuteC()
    return err
}

// ExecuteC executes the command.
func (c *Command) ExecuteC() (cmd *Command, err error) {
    // Regardless of what command execute is called on, run on Root only
    // 递归寻找最上层
    if c.HasParent() {
        return c.Root().ExecuteC()
    }
}

再来看一次 Command 结构体定义

type Command struct {
    // 子命令
    commands []*Command
    // 父命令
    parent *Command
}

(2) 通过将传入的命令保存到 []*Command 切片中, 实现了命令树的 组合

c.commands = append(c.commands, x) // (2)

且同时 实现了 同一个命令挂载到多个父命令上

root.AddCommand(sub1, sub2) // (a)
sub1.AddCommand(sub2) // (b)

commands 是一个切片, 用于保存 挂载 上来的子命令。 但是, 这里需要注意, 由于 *Command 是指针类型, 意味着在任何修改, 都可能影响其他调用的地方。

对于 sub2 而言, (a)处父节点是 root(b)处父节点是 sub1最终父节点是 sub1。 但不影响 sub2 同时是 rootsub1 的子命令。

总体来说, cobra 命令节点 独立而又统一

互相吹捧, 共同进步

欢迎和我一起学习进步, 如果有什么问题, 可以给我私信留言。 或者

  1. 加我好友 线下讨论。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值