If you haven’t heard of Golang’s not addressable concept, it doesn’t matter, it literally means that you can’t get the address of a value. Let’s start with a simple example.
m is of type
map[int]string and contains only one key-value pair. Printing the address of the value of this key-value pair directly compiles with the error:
cannot take the address of m , and cannot get the address of the value in
map. This is a relatively common example of non-addressability. The reason is also relatively simple. The
map type is implemented through a hash table, and as the number of elements of
map increases, the expansion may be triggered, then the location of the value of
map changes, i.e. its address will change, so the value of
map cannot be addressed. On the other hand, if the element does not exist in
map, it returns a zero value, which is an immutable object and cannot be addressed (immutable objects in golang are not addressable, such as constants).
For a slightly more complex example, the Golang wiki’s MethodSets has the following sentence.
The concrete value stored in an interface is not addressable, in the same way that a map element is not addressable.
It means that a concrete value assigned to an
interface type is not addressable, just like an element in a
map. Instead of understanding this statement, let’s look at an example.
Male type with two methods, a
getName() method for the value recipient and a
setName() method for the pointer recipient. In
m1 is a value object of type
m2 is a pointer object of type
Male, and the
setName() methods are called on both objects, and can be called and executed normally. Then the question arises.
m1is a value type object (caller), why can the pointer receiver method
m2is a pointer type object (caller), what can call the value receiver method
For the first question, when the value caller calls the pointer recipient method, the compiler uses the caller’s reference (fetch address) to call the method by default, i.e., the compiler implicitly converts to
For the second problem, when a pointer caller calls a value receiver method, the compiler will by default dereference (take the value) of the pointer caller to the value type, i.e. the compiler implicitly converts to
The above example is still relatively well understood, and many books and articles explain this problem.
Then look at another example.
This example is very similar to the one just given, except that it adds a
Person type interface, defines the
Male type, implements the
getName() method for value recipients, and implements the
setName() method for pointer recipients.
Initializing the value object of
Male to assign to the
Person interface, noted as
p1, directly reports an error.
The error is that variables of type
Male cannot be assigned to
Person because type
Male does not implement the
Person interface (
setName is the pointer recipient method).
So why is it that in the previous example, the compiler can automatically take the address of the value type (non-interface type) and do an implicit conversion, but not here? The reason is the opening sentence.
The concrete value stored in an interface is not addressable.
The value type assigned to the interface is not addressable, and since it is not addressable, there is no way for the compiler to automatically take its address and pass it to the method received by the pointer.