[Translate] effective go Blank identifier

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Blank identifier

Go defines a special identifier _, called the blank identifier. The blank identifier can be used in a declaration to avoid declaring a name, and it can is used in an assignment to Discar D A value. This definition makes it useful in a variety of contexts.

Go has a special identifier _ is a blank identifier it can be used to avoid naming a variable and also to discard a value when assigning a value


Multiple assignment

If an assignment requires multiple values on the left side, but one of the values won't be used by the program, using T He blank identifier in the assignment avoids the need to create a dummy variable. We saw one example of the discussion of for loops above.

If you assign a value you need to assign values to multiple variables at the left of the assignment statement, which is the equal sign, but one of the values will not be used again by the program to use black identifier to avoid creating a useless variable look at the following example:

Sum: = 0for _, Value: = range Array {//We do not care about the value of index    sum + = value}


Another common use was when calling a function that returns a value and an error, but only the error is important.

Another common place is that function calls return a value and error but we only care about this error:

If _, Err: = OS. Stat (path); Os. Isnotexist (Err) {FMT. Printf ("%s does not exist\n", Path)}


A final use, that is, more common than it should was to discard, the error from a function, is not expected to fail. This is usually a mistake:when the function does fail, the code would continue on and probably panic dereferencing a nil p Ointer.

There is also a common place to discard the error returned by the function call and the expected result of this function call is that it must not produce an error this usage may be wrong if the function does return an error The next code may produce panic

Always check the Errors:this program crashes if path does not exist.fi, _: = OS. Stat (Path) fmt. Printf ("%s is%d bytes\n", path, fi.) Size ())


Unused Imports and variables

Go defines that it's an error to import a package without using it, or to declare a variable without using its value. Unused Imports bloat A program and lengthen compiles unnecessarily; A variable that's initialized but not used are at least a wasted computation and perhaps indicative of a larger bug. Of course, both of these situations also arise in programs that is under active development, as you test and refine your Code.

In Go if you import a package but have to use it go will think it is a wrong state to compile the import package without it can be unexpected and add unnecessary trouble to the compilation has been initialized but not used variables will waste computing resources and after a long time or someone else to accept Can not notice this and lead to serious bugs


For example, the this program, there is, unused imports (FMT and IO) and an unused variable (greeting).

For example, in the following code, there are two imported packages and one variable is not used:

Package Mainimport (    "FMT"    "IO") func main () {    Greeting: = ' Hello, world '}


Top-level blank declarations referring to the packages would silence the unused import errors. By convention, these declarations should come immediately after the imports, as a reminder to clean things up later. Similarly, assigning greeting to a blank identifier would silence the unused variable error.

The blank declaration at the global level suppresses imports but does not use errors that are normally required to make a blank declaration immediately after importing a package that will not be used

Package Mainimport (    "FMT"    "io") var _ = Fmt. Printfvar _ io. Readerfunc Main () {    Greeting: = "Hello, world"    _ = Greeting}


Import for side effect

An unused import like FMT or IO in the last section should eventually be used or Removed:blank assignments identify code As a work in progress. But sometimes it was useful to import a package with only for its side effects and without any explicit use. For example, during it init function, the NET/HTTP/PPROF package registers HTTP handlers this provide useful debugging in Formation. It has a exported API too, but most clients need only the handler registration. In this situation, it's conventional to rename the same to the blank identifier:

No useful import like the FMT and IO packages in the above code should eventually be used or removed to make the blank declaration is a reminder of the role of the code we are still in the improvement but sometimes we really need to import those unused packages because we want to use some of the content in the package, such as package net/ht init function in Tp/pprof its init function registers a handler that handles HTTP requests this handler provides debugging information Net/http/pprof there are APIs that can be exported but in most cases we just want the functionality provided by the INIT function If you encounter this scenario, the usual practice is to use blank identifier to give the wrap name when importing:

Import _ "Net/http/pprof"

This form of import makes clear that the package is being imported for its side effects, because there are no other POSSIBL e Use of the package:in this file, it doesn ' t has a name.

This form of import explicitly informs us that importing this package is a certain additional effect of the package.


Interface Checks

As we saw in the discussion of interfaces above, Go does not require a type to declare explicitly Terface. It implements the interface by simply implementing the required methods. This makes Go programs more lightweight and flexible, and it can avoid unnecessary dependencies between packages. Most interface conversions is static, visible to the compiler, and therefore checked at compile time. For example, passing an *os. File to a function expecting an IO. Reader would not compile unless *os. File implements the IO. Reader interface.

As we discussed interface, go does not require that a type must explicitly declare that it implements the interface as long as the function defined in the interface is implemented and the corresponding interface is implemented, which makes the GO program most lightweight and flexible, and the Go program avoids unnecessary packet dependencies. Most of the interface conversions are static to the compiler is visible, so go at compile time check the interface such as to only accept IO. The function of reader is passed *os. File will cause compilation to pass unless *os. File implements the Io.reader interface


However, some types that is used only to satisfy dynamic interface checks. For example, the Encoding/json package defines a Marshaler interface. If the JSON encoder encounters a type implementing that interface, the encoder would let the type convert itself to JSON in stead of using the standard conversion. This check is do only at runtime, with the code like:

However, some types are only used to meet the requirements of dynamic interface checking, such as the Encoding/json package defines the marshaler interface if the JSON decoder encounters a type decoder that implements the interface, it uses this type of its own method to convert to JSON instead of using the standard conversion method This check only occurs at run-time code as follows:

M, OK: = val. (JSON. Marshaler)


If A type-for example, JSON. Rawmessage-intends to customize it JSON representation, it should implement JSON. Marshaler, but there is no static conversions that would cause the compiler to verify this automatically. A declaration can used to add such a check:

If JSON. The rawmessage type wants to customize JSON expression JSON. The Rawmessage type needs to implement the Json.marshaler interface but the conversion is not static and the compiler cannot check if there is an error that can be declared to require the compiler to do the checking:

var _ json. Marshaler = (*mymessage) (nil)

As part of type-checking this static assignment of a *rawmessage to a Marshaler, the Go compiler would require that *rawmes Sage implements Marshaler. Using The blank identifier here indicates so the declaration exists only for the type checking, not to create a variable . Conventionally, such declarations is used only when there is no static conversions already in the code.

This declaration statement assigns *rawmessage to the marshaler go compiler will require *rawmessage to implement the marshaler interface here the meaning of the blank declaration is that this assignment is only for type checking instead of creating a variable generally speaking This is used only if there are no other static transformations in the code

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.