package main import "fmt" type Aer interface{ Name()string PrintName() } type A struct { } func (a *A) Name() string { return "a" } func (a *A) PrintName() { fmt.Println(a.Name()) } type B struct { A } func (b *B) Name() string { return "b" } func getAer() Aer { return &B{} } func main() { a := getAer() a.printName() }
In this implementation, golang outputs a. This implementation violates the usual implementation of b in C, Java, and Python. Due to the thinking of the above languages Once a habit has been formed, this implementation will lead to many unexpected things.
Yesterday, a brother with praise in the golang practice group
(this brother knew the above question I asked and said that this is the implementation method of golang) asked, When UnmarshalJSON, why the Test field was not assigned a value, and raised issue
in golang. His code is as follows:
package main import ( "encoding/json" "fmt" ) type request struct { Operations map[string]op `json:"operations"` } type op struct { operation Test string `json:"test"` } type operation struct { Width int `json:"width"` Height int `json:"height"` } func (o *operation) UnmarshalJSON(b []byte) error { type xoperation operation xo := &xoperation{Width: 500, Height: 500} if err := json.Unmarshal(b, xo); err != nil { return err } *o = operation(*xo) return nil } func main() { jsonStr := `{ "operations": { "001": { "test":"test", "width": 100 } } }` req := request{} json.Unmarshal([]byte(jsonStr), &req) fmt.Println(req) }
The essence of this problem is the same as the one I raised, because The operation is embedded in the op, so there is UnmarshalJSON, which conforms to the Unmarshaler interface in the json package. Therefore, when the interface is used internally for processing, the op is satisfied, but what is actually processed is the operation, that is, the operation is used as the entity to perform UnmarshalJSON. Resulting in weird error messages.
I think this is a very ugly place in golang implementation.
According to what Brother Mouse said, if the language implementation rules are known, but it is still easy to make mistakes, then it is a pitfall.
This golang pitfall will probably have to be filled in the future.