This is the fourth day of my participation in the Gwen Challenge.More article challenges

In this article, take notes on interface learning

def say(interface) :
    interface.hello()
Copy the code

In the code above, py only checks whether the interface type has hello() at runtime.

Go, as a static language, can detect type mismatches at compile time, and there is no explicit requirement to implement interfaces.

Value receiver/pointer receiver

Here is the conclusion (there is nothing to explain…) :

  1. The receiver – >*Gopher-> It is likely that changes will be made to the recipient properties in the method, affecting the recipient properties
  2. The receiver – >Gopher-> The receiver itself is not affected in the method
  3. When you implement a method whose receiver is a value type, you can automatically generate a method whose receiver is a pointer type, because neither affects the receiver
  4. Bottom line: If you implement a method whose receiver is a value type, you implicitly implement a method whose receiver is a pointer type

When to use it?

  • *Gopher
  1. Method needs to modify the recipient’s value
  2. The recipient itself costs a lot in the copying process, and copying with Pointers is more efficient
  • Gopher
  1. Type isGoA primitive type built into the
  2. See you get used to

The type system

Myslice []string, sliceType is the type represented by slice itself

This actually explains:

// Alias of the string type
type mytype1 = string
// myType2 user-defined type
type mytype2 string
Copy the code

The comments make it clear that these two types are completely inconsistent. The corresponding type metadata is also completely different.

Internal implementation

Iface and eface are both low-level constructs that describe interfaces in Go:

  1. ifaceContains methods for the interface described
  2. efaceIs an empty interface that contains no methods:interface{}

Say first iface:

type eface struct {
	_type *_type
	data  unsafe.Pointer
}

type iface struct {
	tab  *itab              // The interface type and the entity type assigned to the interface
	data unsafe.Pointer     // Interface specific value -> pointer to heap memory
}

type itab struct {
	inter *interfacetype
	_type *_type            // The type of value that the interface actually points to
	hash  uint32            // '_type. Hash'
	_     [4]byte
	fun   [1]uintptr        // the interface method corresponds to the method address of the concrete implementation, which is analogous to the 'C++ virtual function table' to implement the dynamic distribution of interface calls
}
Copy the code

With the above data structure in mind, let’s look at how the interface is constructed:

A number of problems

Note some of the issues involved in the interface

In the conversionnil

type MyError struct {}

func (i MyError) Error(a) string {
	return "MyError"
}

func main(a) {
	err := Process()
	fmt.Println(err)

	fmt.Println(err == nil)}func Process(a) error {
	var err *MyError = nil
	return err
}
Copy the code

We know above:

  1. struct MyError -> interface error(realizedinterface error)
  2. return *MyErrorReturns this type but with a value ofnil
  3. Above we get:
    • The returnederrThe dynamic type is:*MyError
    • Dynamic value returned:nil

interfaceThe interface value is onlyDynamic typeDynamic valuefornilWhen, can sayinterface == nil

So the above results are as follows. Because the dynamic type is *MyError, it’s not equal to nil; But the value is nil, so print nil:

<nil>
false
Copy the code