From f8284b64cecf38338cf62ddc6398c0a9fe655326 Mon Sep 17 00:00:00 2001
From: Russ Cox
+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 be used in an assignment to discard a value.
+This definition makes it useful in a variety of contexts.
+
+If an assignment requires multiple values on the left side, +but one of the values will not be used by the program, +using the blank identifier in the assignment avoids the need +to create a dummy variable. +We saw one example of this in the discussion of +for loops above. +
++sum := 0 +for _, value := range array { + sum += value +} ++ +
+Another common use is when calling a function that returns +a value and an error, but only the error is important. +
++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 be is to +discard the error from a function that is not expected to fail. +This is usually a mistake: when the function does fail, the code +will continue on and probably panic dereferencing a nil pointer. +
++// Always check errors: this program crashes if path does not exist. +fi, _ := os.Stat(path) +fmt.Printf("%s is %d bytes\n", path, fi.Size()) ++ +
+Go defines that it is 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 is initialized but not used is at least +a wasted computation and perhaps indicative of a +larger bug. +Of course, both of these situations also arise in programs +that are under active development, as you test and refine +your code. +
+
+For example, in this program, there are two unused imports
+(fmt
and io
)
+and an unused variable (greeting
).
+
+Top-level blank declarations referring to the packages
+will 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
+will silence the unused variable error.
+
+ +
+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 is useful to import a package only for its
+side effects, without any explicit use.
+For example, during its init
function,
+the net/http/pprof
+package registers HTTP handlers that provide useful
+debugging information. It has an exported API too, but
+most clients need only the handler registration.
+In this situation, it is conventional to rename the package
+to the blank identifier:
+
+import _ "net/http/pprof" ++
+This form of import makes clear that the package is being +imported for its side effects, because there is no other possible +use of the package: in this file, it doesn't have a name. +
+ +
+As we saw in the discussion of interfaces above,
+Go does not require a type to declare explicitly that it implements an interface.
+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 are static, visible to the compiler,
+and therefore checked at compile time.
+For example, passing an *os.File
to a function
+expecting an io.Reader
will not compile unless
+*os.File
implements the io.Reader
interface.
+
+However, some types that are 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 will let the type convert itself to JSON instead of using the standard
+conversion.
+This check is done only at runtime, with code like:
+
+m, ok := val.(json.Marshaler) ++
+If a typeâfor example,
+json.RawMessage
âintends
+to customize its JSON representation, it should implement
+json.Marshaler
, but there are no static conversions that would
+cause the compiler to verify this automatically.
+A declaration can be used to add such a check:
+
+var _ json.Marshaler = (*MyMessage)(nil) ++
+As part of type-checking this static assignment of a
+*RawMessage
to a Marshaler
,
+the Go compiler will require that *RawMessage
implements Marshaler
.
+Using the blank identifier here indicates that
+the declaration exists only for the type checking,
+not to create a variable.
+Conventionally, such declarations are used only when there are
+no static conversions already present in the code.
+