In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains the "Go source code reading what is the flag package", the article explains the content is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "Go source code reading what is the flag package" bar!
Brief introduction
The flag package is the package used to parse command-line arguments in Go. Why choose it as the first package to read, because it has a small amount of code. Its core code is only a flag.go file with less than 1000.
File structure
The file structure of the flag package is very simple, just one layer. There are five files in a folder, and their functions are as follows:
Flag.go
The core package of flag, which implements all the functions of command line parameter parsing
Export_test.go
A testing utility that defines all the basic variables and functions needed for testing
Flag_test.go
Flag test file, which contains 17 test units
Example_test.go
Flag sample file, which introduces three common usage examples of the flag package
Example_value_test.go
Sample file for flag, which introduces a more complex example
Run the test
Let me first introduce the operating environment of Go.
# installed through brew install go, the source code read at $GOROOT/srcGOROOT=/usr/local/opt/go/libexec# is downloaded through go get-v-d github.com/haojunyu/go, and the source code location is $GOPATH/src/github.comGOPATH=$HOME/go
Separately test the pits that the flag package has stepped on:
Cannot be tested against a single file, it needs to be tested against a package.
Let's focus on the export_test.go file, which is part of the package flag of the flag package, but it does exist specifically for testing, and to put it bluntly, it's just a ResetForTesting method that clears the state of all command parameters and sets the Usage function directly. This method is frequently used in test cases. So running the following command alone will result in an error "flag_test.go:30:2: undefined: ResetForTesting"
# Test the current directory (error) go test-v. # Test package go test-v flag
The source code for the go test-v flag test is under $GOROOT/src (in my current test environment)
After specifying the flag package, the actual running source code is under $GOROOT, which should have something to do with the way I install it.
Summary interface transformation can achieve functions similar to templates in C++.
A structure type called Flag is defined in the flag package, which is used to hold a command parameter, which is defined as follows.
/ / the A Flag represents the state of a flag.// structure Flag represents all the information about a parameter, including name, help information, actual value and default value type Flag struct {Name string / / name as it appears on command line name Usage string / / help message help information Value Value / / value as set implements the interface DefValue string / / default value (as text) of the value / assignment method For usage message default value}
The value of the command parameter is a Value interface type, which is defined as follows:
/ / Set is called once, in command line order, for each flag present.// The flag package may call the String method with a zero-valued receiver,// such as a nil pointer.// interface Value is an interface, which is used in the structure Flag to store the dynamic values of each parameter (various parameter types) type Value interface {String () string / / value method Set (string) error / / assignment method}
Why would you do that? Because doing so can achieve functions similar to templates. As long as any type T implements the String and Set methods in the Value interface, then the variable v of this type T can be converted to the Value interface type, using String to take the value and Set to assign the value. In this way, it can perfectly solve the operation purpose of different types using the same code, and has the same effect as the templates in C++.
Functional vs method
Both a function and a method are a set of statements that perform a task together. The difference is that the caller is the package package, while the caller of the method is the receiver receiver. In the source code of flag, there are too many functions with only one line, that is, to call a method with the same name with the variable CommandLine in the package.
/ / Parsed reports whether f.Parse has been called.// Parsed method: whether the command line argument has parsed func (f * FlagSet) Parsed () bool {return f.parsed} / / Parsed reports whether the command-line flags have been parsed.func Parsed () bool {return CommandLine.Parsed ()} new vs make
New and make are two memory allocation primitives in the Go language. Both do different things and target different types. New and other programming languages in the keyword function is similar, are to apply for a section of memory space to store the corresponding type of data, but with some differences, the difference is that it will set the space to zero. That is, new (T) requests a zero memory space on the heap based on the type T and returns the pointer * T. Make only builds for slice, map, and channel data types T and returns a value of type T that has been initialized (not zero). The reason is that all three data types are reference data types and must be initialized before using them. Just like a slice is a descriptor with three items, including a pointer to an array, length, and capacity. The process of creating a variable of the corresponding type through make is to allocate a space first, and then create the corresponding type variable according to the corresponding descriptor. For details about make, you can see the Go language design and implementation written by draveness.
/ / Bool defines a bool flag with specified name, default value, and usage string.// The return value is the address of a bool variable that stores the value of the flag.func (f * FlagSet) Bool (name string, value bool, usage string) * bool {p: = new (bool) f.BoolVar (p, name, value, usage) return p} / / sortFlags returns the flags as a slice in lexicographical sorted order.// sortFlags function: sort command parameters in dictionary order And return the slice func sortFlags of Flag (flags map [string] * Flag) [] * Flag {result: = make ([] * Flag, len (flags)) I: = 0 for _, f: = range flags {result [I] = fi Qing +} sort.Slice (result, func (I) J int) bool {return result [I] .Name < result [j] .Name}) return result} pointer assigned to interface variable
The interface in Go has two meanings. The first layer is the signature of a set of methods (not functions), which requires the recipient (specific type T or specific type pointer * T) to implement the details; the other layer is a type that can accept all the recipients that should be accepted. If you have a deep understanding of the concept of interface, you can read the interface designed and implemented in Go language. In the StringVar method in the flag package, newStringValue (value, p) returns the * stringValue type, and the type (recipient) implements the Value interface (String and Set methods), so the type can be assigned to the Value interface variable.
/ / StringVar defines a string flag with specified name, default value, and usage string.// The argument p points to a string variable in which to store the value of the flag.// StringVar method: assign the default value of the command line argument to the variable * p, and generate the structure Flag and place it in the recipient f.formalfunc (f * FlagSet) StringVar (p * string, name string, value string, usage string) {f.Var (newStringValue (value, p), name) Usage) / / the returned value of newStringValue is * stringValue type It can be assigned to the Value interface because the recipient defined when newStringValue implements the Value interface is that there is a flag_ test package in the * stringValue} flag folder
There is a flag_test package under the flag folder because it contains the core code flag.go and test code * _ test.go. These two pieces of code are not distinguished by folders. So the purpose of the flag_test package is to distinguish the test code from the core code. Only the core code is used when the package is referenced.
/ / example_test.gopackage flag_test scope
Both the scope of Golang variables and the scope of GO in the Bible are described in detail. The former is easier to understand and the latter is more professional. In the TestUsage test sample of the flag package, because func () {called=true} is a function defined in the function TestUsage and passed directly to the ResetForTesting function as a formal parameter, the function is at the same level as the local variable called, and of course it is reasonable to assign a value to the variable in this function.
The scope of / / called variable func TestUsage (t * testing.T) {called: = false / / the scope of variable called ResetForTesting (func () {called = true}) if CommandLine.Parse ([] string {"- x"}) = = nil {t.Error ("parse did not fail for unknown flag")} else {t. Error ("hh")} if! called {t.Error ("did not call Usage for unknown flag")}} Thank you for reading The above is the "Go source code to read what is the flag package" content, after the study of this article, I believe that we read the Go source code what is the flag package of this problem has a deeper understanding, the specific use of the situation also needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.