30

I'm not sure I understand the reasoning behind this example (taken from here), nor what it is trying to communicate about the Go language:

package main

import (
    "flag"
    "fmt"
)

func main() {
    f := flag.NewFlagSet("flag", flag.ExitOnError)
    f.Bool("bool", false, "this is bool flag")
    f.Int("int", 0, "this is int flag")

    visitor := func(a *flag.Flag) {
        fmt.Println(">", a.Name, "value=", a.Value)
    }

    fmt.Println("Visit()")
    f.Visit(visitor)
    fmt.Println("VisitAll()")
    f.VisitAll(visitor)

    // set flags
    f.Parse([]string{"-bool", "-int", "100"})

    fmt.Println("Visit() after Parse()")
    f.Visit(visitor)
    fmt.Println("VisitAll() after Parse()")
    f.VisitAll(visitor)
}

Something along the lines of the setup they have but then adding a

int_val := f.get("int")

to get the named argument would seem more useful. I'm completely new to Go, so just trying to get acquainted with the language.

lollercoaster
  • 15,969
  • 35
  • 115
  • 173
  • 3
    https://gobyexample.com/command-line-flags is a great example. – elithrar Nov 04 '13 at 06:16
  • You need a FlagSet if you want to pass arguments to parse in the code of the program `f.Parse([]string{"-bool", "-int", "100"})`. The global `flag.Parse()` function doesn't accept an argument to parse. This code example can than be run in the tour of go code pad where you can't provide command lines arguments. – chmike Nov 25 '16 at 13:26

1 Answers1

57

This is complicated example of using flag package. Typically flags set up this way:

package main

import "flag"

// note, that variables are pointers
var strFlag = flag.String("long-string", "", "Description")
var boolFlag = flag.Bool("bool", false, "Description of flag")

func init() {
    // example with short version for long flag
    flag.StringVar(strFlag, "s", "", "Description")
}

func main() {
    flag.Parse()
    println(*strFlag, *boolFlag)
}       
mechmind
  • 1,732
  • 13
  • 11
  • 5
    Yes this is the preferred way. Another nice trick is that you can use the flag module from *any* module splitting module specific flags in a more maintainable way – fabrizioM Nov 04 '13 at 05:45
  • So `init()` is always run before `main()` and its variables are accessible inside `main`? Also `strFlag` is a pointer, and so the * is used to retrieve the value? – lollercoaster Nov 04 '13 at 05:46
  • @fabrizioM: from any module? what does that mean, exactly? coming from python background, so seems like you mean that other files we import here from my project could also use the same flag variables? that would be a cool thing. – lollercoaster Nov 04 '13 at 05:47
  • 1
    @lollercoaster yep try to put flags inside a module that is not main. Remember that if you want to access those vars from outside the module they need to be capitalized. – fabrizioM Nov 04 '13 at 06:42
  • 8
    `init()`s run before main (all of them - you can have init in every file in your module and even multiple `init`s in same file. Order of execution for `init`s is undefined, so do not call `flag.Parse` inside them). Init functions have another limitation - goroutines started by them will not start until main is started. Variables in `init` does not share with other functions, `strFlag` just global variable. – mechmind Nov 04 '13 at 07:04
  • 1
    @mechmind What do you mean by "and even multiple inits in same file", can you provide an example of this please. – Ian Lewis Jul 09 '14 at 13:07