go labs

A Rubyist Learning Go – Command Line Flags

In our last installment, we learned how to write a basic Go command line program. Now, we want to tell the program who to greet instead of simply greeting the world. To accomplish this, we will use Go’s command line library, flag.

Here is the complete program:

package main

import "flag"
import "fmt"

func main() {
name := flag.String("name", "world", "name to greet")
flag.Parse()

fmt.Println("Hello, " + *name + "!")
}

The first thing you may notice is the formatting is a bit different than Ruby. Go contains a tool called gofmt that is used to format code to the canonical Go format. I am not going to go into the details here but there is a good article about what the creators of Go saw as the benefits of default fomatting and some unintended consequences.

We have also changed the main() function to get the command line flags. There are two parts to this process, defining the flags and parsing them.

Defining flags is as simple as assigning a variable called “name” (using short variable declaration) with the value from a function on the flag package that returns a pointer to the flag (yes Go has pointers). This function takes three parameters, the name of the flag, the default value of the flag and the help string.

name := flag.String("name", "world", "name to greet")

The second part is the parsing of the flags:

flag.Parse()

This actually assigns the passed in flags. If you aren’t seeing your passed in flags and getting the defaults, you have probably forgotten this line.

The last part is using the flag to print out the name.

fmt.Println("Hello, " + *name + "!")

“name” is a pointer to a flag so you have to dereference it to get the value.

To see it all in action, you can type “go run hello.go -help” to get the usage.

Usage of /var/folders/3j/853004017fsd42jp9glcsych0000gn/T/go-build026175841/command-line-arguments/_obj/exe/hello:
-name=”world”: name to greet
exit status 2

Or “go run hello.go -name=mike” to run the program.

Pretty nice in my opinion. Next time we will take a look at building Go executables, another option for passing in command line arguments and creating a simple HTTP server.

Side note: There is another way to define command line flags.

package main

import "flag"
import "fmt"

var name string

func main() {
        flag.StringVar(&name, "name", "world", "name to greet")
        flag.Parse()

        fmt.Println("Hello, " + name + "!")
}

This one declares a not exported variable called “name” and then assigns the value of the argument to that variable. Since name is now a string (as noted by the type declaration), there is no need to dereference it when outputting the value. I’m not sure which I like more…only time will tell.