Our Latest News

Parsing of command line arguments in the go language

Some time ago, a group of friends asked a go language question in the group.

It is that there is a main function in main.go that calls a hello() function in another demo.go. The main.go and hello.go belong to the same main package. However, running go run main.go in the main.go directory gives the error that the hello function is not defined.

The code structure is as follows.

main.go is as follows.

package main

import “fmt”

func main() {

fmt.Println(“my name is main”)

hello()
}
hello.go is as follows.

package main

import “fmt”

func hello() {
fmt.Println(“my name is hello”)
}

At that time I looked at the thought that he GOPATH configuration problems, and then they also tried in accordance with this, reported the same error, checked on the Internet, there are also two articles about this error, also provides a solution, that is, with go run main.go hello.go, tried is indeed possible.

Although it is a very simple problem, it also involves the parsing of command line arguments at the bottom of the go language. Then let’s analyze the underlying implementation of the language and see what the underlying layer does and why it reports this error.

Analysis.

The following uses to the Go SDK version 1.8.3

The basic commands supported by go in this version are the following 16.


In the main.go file under the src/cmd/go package of the Go SDK, the array of commands of type Command provides support for these 16 commands.

We first know that the go language initialization process is as follows.

Before executing the main function main in main.go, initialize the packages imported in order, and finally initialize the types and variables in main.go. When initializing the commands array, since the cmdRun definition lies in run.go under the same package as main.go, then go ahead and initialize the variables in run.go and the The following code initializes cmdRun to Command type and then executes init() function.


In init(), runRun (actually type is a method to handle arguments after run) is assigned to cmdRu.run. addBuildFlags(cmdRun) is mainly to add command line arguments after run (e.g. -x is to print all commands used during its execution and execute them at the same time). The other 15 commands are similar to cmdRun, each with its own run implementation.

Let’s look at the main code in main.go.


This code iterates through the commands array, and when it reaches cmdRun, cmd.Name() actually gets the first word of cmdRun.UsageLine run

CustomFlags is not initialized so it is false, go to the else branch, then start parsing the args command line parameters, args[1:] that is, take all the parameters after run. Run(cmd, args), for cmdRun, here the execution is run.go in the first line of init() assignment cmdRun.run (above, this is a function, different commands to achieve different ways), that is, to execute run.go in the runRun function, the function is mainly the command line parameters when file to handle, if it is _test for the suffix, that is, the test file, direct error. If it is a directory also directly report an error (and go run can only contain a go file containing the main function). Notice that there is this line.

p := goFilesPackage(files)
goFilesPackage(files) in addition to checking the file type and suffix, but also into the stack, load, out of the stack and other operations, because the startup did not pass hello.go, so the system loaded main.go can not find hello function, resulting in an error.

    GET A FREE QUOTE

    FPGA IC & FULL BOM LIST

    We'd love to

    hear from you

    Highlight multiple sections with this eye-catching call to action style.

      Contact Us

      Exhibition Bay South Squre, Fuhai Bao’an Shenzhen China

      • Sales@ebics.com
      • +86.755.27389663