是否可以将可变参数与标志包用法结合使用?

时间:2019-01-02 15:43:39

标签: go

我希望函数以有效的方式接受可选参数。

阅读类似的文章使我陷入了可变参数的问题,我正在尝试将其与flag软件包一起实现(只是寻找用户能够运行他们选择的可用命令行标志的任何替代方法。 这是我的标志包用法:

func main() {
    var target string
    var method string
    flag.StringVar(&target, "target", "http://google.com/robots.txt", "Target address")
    flag.StringVar(&method, "method", "GET", "Method")
    flag.Parse()

    requests.MakeRequest(target, method)
}

这是可变参数args函数的示例:

func foo(params ...int) {
    fmt.Println(len(params))
}

func main() {
    foo()
    foo(1)
    foo(1, 2, 3)
}

我可以将两者结合吗? 如果这不可能-那么如何将给定参数的主程序用户传递给可变参数函数呢?

1 个答案:

答案 0 :(得分:1)

您的问题显示了误解,什么是可变参数。

您已经意识到,当函数的参数数量变化时,将使用variadics。您尝试使用此概念来传递可变数量的已解析命令行参数。从许多方面来看,这是一个坏主意。显而易见,您正在将命令行参数与代码中标志和参数的分布耦合在一起。另一个是,可变参数会丢失位置信息。您希望如何识别收到的5个参数中的哪个4个?

您应该定义一个结构来保存代码的标志,并编写一个命令行解析器,该解析器根据默认值和给定的命令行选项填充或创建此结构。 然后,该结构用于在整个应用程序中提供标志和选项。

实际上,这可能是这样的:

type options struct {
    target string
    method string
}


func main() {
    config := parseCommandLine()
    theRealStuffHappensHere(config)
}

func theRealStuffHappensHere(config options) {
    if config.method == "GET" {
    // ...
    }
}

func parseCommandLine() options {
    var config options
    flag.StringVar(&(config.target), "target", "http://google.com/robotstxt", "Target address")
    flag.StringVar(&(config.method), "method", "GET", "Method")
    flag.Parse()

    return config
}

可变参数在fmt包中被大量使用,其中所需参数的数量取决于格式字符串中占位符的数量。您的用例不匹配。