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…) :
- The receiver – >
*Gopher
-> It is likely that changes will be made to the recipient properties in the method, affecting the recipient properties - The receiver – >
Gopher
-> The receiver itself is not affected in the method - 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
- 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
- Method needs to modify the recipient’s value
- The recipient itself costs a lot in the copying process, and copying with Pointers is more efficient
Gopher
- Type is
Go
A primitive type built into the - 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:
iface
Contains methods for the interface describedeface
Is 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:
struct MyError
->interface error
(realizedinterface error
)return *MyError
Returns this type but with a value ofnil
- Above we get:
- The returned
err
The dynamic type is:*MyError
- Dynamic value returned:
nil
- The returned
interface
The interface value is onlyDynamic type 和 Dynamic valuefornil
When, 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