This is a creation in Article, where the information may have evolved or changed.
In golang , the interface value is a two-part, part of the interface type, and the other part is the value of the type, we call it dynamic type and dynamic value.
How should this concept be understood? Let's look at a piece of code first:
var w io.Writer // type-<nil>w = new(bytes.Buffer) // type-*bytes.Bufferw = nil // type-<nil>
Here you define a variable and w then assign it a value, and you can see that the type of the variable w is different and can be used fmt %T to view its dynamic type.
fmt.Printf("%T\n",w)
In the first row to define the variable W, declare its type io.Writer , here is the true meaning of the null interface, why is an empty interface, is its type and value are nil , here can be used == or != come and nil make judgments.
w == nil // return true
When the second behavior variable w is assigned a value, w the dynamic type *bytes.Buffer is, and then the dynamic value is a pointer to the newly allocated buffer.
package bytestype Buffer struct { buf []byte // contents are the bytes buf[off : len(buf)] off int // read at &buf[off], write at &buf[len(buf)] bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation. lastRead readOp // last read operation, so that Unread* can work correctly.}
You can call Writer methods in the interface at this point:
w.Write([]byte("ok"))
By the way, if you invoke the method with the variables in the first row w Write , the program will error, and any method that calls an empty interface value will be generated Panic .
The effect of the third behavior assignment is the same as it was w originally, with dynamic type and dynamic value being nil an empty interface.
Speaking of which, it is possible to understand the meaning of the interface value, but there is a problem, that is, an interface is empty and an interface contains null pointers is a matter? Let's look at a piece of code:
func test(w io.Writer) { if w != nil{ w.Write([]byte("ok")) }}func main() { var buf *bytes.Buffer test(buf)}
If the execution of this procedure, the return error, we have a little analysis, in main() , we first declared a buf variable, type is a *bytes.Buffer pointer type, when the function is called, the test() parameters are w assigned to dynamic type *bytes.Buffer , dynamic value is nil , wthat is, a non-null interface that contains a null pointer value. So in the w != nil judgment, this equation is set up, but here also reflects a phenomenon from the side, that is, this parameter is a value copy, then see here, this code should be better modified:
var buf io.Writer // buf = new(bytes.Buffer)
Let's take another look at the code:
type Test interface {}type Test1 interface { TestFunc()}type Structure struct { a int}func (s *Structure) TestFunc(){ fmt.Println("Ok, Let's rock and roll!")}func fTest(t Test) { fmt.Println(t == nil)}func fTest1(t1 Test1){ fmt.Println(t1 == nil)}func fStructure(s *Structure){ fmt.Println(s == nil)}func main() { var s *Structure = nil fTest(s) // false fTest1(s) // false fStructure(s) // true s.TestFunc() // Ok, Let's rock and roll!}
Executes the code, is it the same as the expected result? Ok, let ' s rock and roll!