GO foreign Language translation project golang.org/doc/effecti…

The type of an interface does not have to explicitly declare that it implements the interface. Instead, a type implements an interface only through methods that implement the interface. In practice, most interface transformations are static and therefore checked at compile time. For example, a function that passes * os.File to an expected IO.Reader interface will not compile unless * os.File implements the IO.

However, some interface checking does occur at run time. There is an instance in the encoding/JSON package that defines the Marshaler interface. When the JSON encoder receives a value that implements the interface, the encoder calls the marshalling method of the value to convert it to JSON instead of performing a standard conversion. The encoder checks this property at run time using a type declaration, such as:

m, ok := val.(json.Marshaler)
Copy the code

If you only need to ask if a type implements an interface, without actually using the interface itself (perhaps as part of error checking), you can use a blank identifier to ignore the value of the type declaration:

if _, ok := val.(json.Marshaler); ok {
    fmt.Printf("value %v of type %T implements json.Marshaler\n", val, val)
}
Copy the code

One place where this happens is that it is necessary to ensure in the package that implements the type that it actually satisfies the interface. If a type (such as json.rawmessage) requires a custom JSON representation, then json.marshaler should be implemented, but no static conversion will cause the compiler to validate this automatically. If the type unexpectedly does not satisfy the interface, the JSON encoder will still work, but the custom implementation will not be used. To ensure correct implementation, use a global declaration with a blank identifier in the package:

var _ json.Marshaler = (*RawMessage)(nil)
Copy the code

In this declaration, the assignment involved in converting * RawMessage to Marshaler requires * RawMessage to implement Marshaler and will check this property at compile time. If the json.marshaler interface changes, the package will no longer compile, and we will notice that it needs to be updated.

The presence of a blank identifier in this construct indicates that the declaration exists only in type checking and is not used to create variables. However, do not do this for every type that satisfies the interface. By convention, such declarations are used only when there is no static transformation in the code, which is a rare event.