This is a creation in Article, where the information may have evolved or changed. #GO语言面向对象编程之接口 (bottom) #Go ' s interfaces-static, checked at compile time, dynamic when asked For-are, for me, the most exciting P Art of Go from a language design point of view. If I could export one feature of Go to other languages, it would be interfaces. Interface in the Go language status from the above author's words can be seen, so for the interface of learning, directly to read some English literature. The following is a description of the:> [Http://jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go], which is mainly based on this document (HTTP/ jordanorelli.com/post/32665860244/how-to-use-interfaces-in-go) ***# #接口的介绍接口是什么? An interface consists of two parts: an interface is a set of methods, but it is also a type, which we first interpret from a set of methods. <font size = 5 Color =red>we ' ll define an Animal as being anything that can speak. This was a core concept in Go ' type system. Instead of designing our abstractions in terms of that kind of data our types can hold, we design our abstractions in term S of what actions we types can execute.</font> this paragraph really do not know how translation can translate the essence of meaning. The general meaning is that we define a animal interface, as long as the object that has the speech function is aniamal. Instead of designing what types of data we can have, we focus on what we can do. We designed the interface as follows: Type Animal interface {Speak () striThe Ng}speak function has no arguments and returns a string type. Any type that has a speak function can be said to implement the animal interface. There is no implements keyword in the go language; If a data type implements an interface auto-decision, consider the following example of implementing an interface: type Dog struct {}func (d dog) Speak () string {return "woof!"} Type Cat struct {}func (c Cat) Speak () string {return "meow!"} Type Llama struct {}func (l Llama) Speak () string {return '????? '} Type Javaprogrammer struct {}func (J Javaprogrammer) Speak () string {return ' Design patterns! '} Here we define four types, each of which has its own speak function. Therefore, all four types implement interface animal. So we can just create a Animal slice and look at each type of output: Func main () {animals: = []animal{cat{}, dog{}, llama{}, Javaprogrammer{}}for _, Animal: = Range Animals {fmt. PRINTLN (animal. Speak ())}}***# #interface {} type interface{} is an empty interface and is a very confusing place to have. Because the empty interface does not have any functions, and because the go language does not have the Implements keyword to identify the implementation relationship of the interface, all types can be considered to implement the interface{}. This means that if you define a function, If the function argument is an empty interface, then the function can accept any type of argument. Func dosomething (v interface{}) {//...} function dosomething can accept any parameter, what is the data type of V in the function? Because previously said interface{} can be implemented by any type, some people think that V is "any type". In fact V is the interface type. Go will do the type conversion during the run, and each variable will have a type when it runs. Here V is the interface{} classType. If the above function is called as follows: data: = []int{1, 2, 3, 4, 5}dosomething (data) This time the compilation has the following error:. \main.go:48:cannot use Data (Type []int) as type []interface {} in argument to dosomething here proves that the interface is a type, not a so-called "arbitrary type." See here if you are still confused, then it is normal, if there is no doubt, then read the preceding things again, or directly read the English text above. * * The interface consists of 2 words: A data type that points to the number of bytes in the interface, and a pointer to a list of methods for that interface, which is not the type of data that is stored. **! [] (Http://i.imgur.com/0tXStyB.png) interface implementation can be seen in this article: [Https://research.swtch.com/interfaces] (https:// Research.swtch.com/interfaces) for the beginning of the Animal instance, we found that we defined the Animal interface slices in the following way: animals: = []animal{cat{}, dog{}, llama{}, javaprogrammer{}} so the two words in the animal[0 in here is a pointer to the cat variable, and the other words points to a list of functions animal this interface. But the careful person may find out why we did not make any forced conversions, such as Animal (cat{}) can directly store the Cat variables inside the interface, because the default is forced conversion. So we don't need to make a strong move on it. For the call of the DoSomething function above, we need to convert the slice explicitly to the slice type before it can be called, so the code is as follows: Func dosomething (v []interface{}) {for _, Data: = Range v {fmt. PRINTLN (data)}}data: = []int{1, 2, 3, 4, 5}value: = Make ([]interface{}, Len (data)) for I: = 0; I < len (data); i++ {Value[i] = data[i]}dosomething (value) This code looks ugly, but there is no perfect thing. []interface{} does not appear as often as you think, because it does not work as well as you think. (the article's exact words, personally feel really ugly O (╯-╰) o). # #Pointers and interfaces Another tip about interfaces is that the interface definition does not specify whether the recipient of the Implementation interface is a pointer or a type. The animal in front of us uses the type as the receiver, if the type is changed to a pointer: func (c *cat) Speak () string {return "meow!"} The compilation will have the following error:. \main.go:41:cannot use cat literal (type cat) as type Animal in array or slice LITERAL:CAT does not implement A Nimal (Speak method has pointer receiver) the wrong meaning is that the function you define Speak is a pointer to the receiver, but you are converting a cat struct into animal. So you can turn the initialized place into a pointer like this: animals: = []animal{new (Cat), dog{}, llama{}, Javaprogrammer{}}animals: = []animal{&cat{}, dog{ }, llama{}, javaprogrammer{}} can be used both ways. But if we change the speak () function to a type as a receiver, we use pointers as arguments. There is no error, because the pointer resolves to its associated data type. The code is as follows: Func (c Cat) Speak () string {return "meow!"} Animals: = []animal{new (Cat), dog{}, llama{}, Javaprogrammer{}}animals: = []animal{&cat{}, dog{}, llama{}, javaprogrammer{}} This is a very difficult situation to understand, as we said before: **everything in Go was passed by value. Every time call a functions, the data you ' re passing to it is copied.** simple understanding is that we invoke the function when the parameters are copied, so you to the formal parameterThe operation is not visible outside because the parameter is just a copy of the argument. Take a look at the two things we said earlier: 1. The pointer can only be invoked when it is received. 2. The type can be invoked with pointers and types as a receive. The following example: Func (T-T) MyMethod (s string) {//...} The function MyMethod function is a func (T, String) type, and the receiver of the function passes inside the function like any other parameter. So for the first case, let's take a look at the author's explanation: Since everything is passed by value, it should be obvious what a *cat method is isn't usable by a Cat valu E Any one Cat value may has any number of *cat pointers. If we try to call a *cat method by using a-Cat value, we never had a *cat pointer to begin with. It means that cat has a lot of pointers to it, so when you use the cat variable to call the *cat method, the cat pointer doesn't know where to point. The second is because when you use the pointer cat to call CAT, because the pointer knows the address it points to, the go language will redefine the *CAT to the variable it points to when it is running. So the go language gives a dog-type pointer *d, and we can call D directly. Speaker, rather than d->speaker in other languages. In fact, if you don't understand, live: <font color = "Red" > pointer receiver functions can only be called by pointers, but function of type receiver, pointer and type can call </font>***# #接口的应用-from HTTP In the request, the object is assumed to design an interface to solve web development problems, we need to parse the HTTP request into some objects (such as a struct to extract the information we want). At first there was no definite design, but what was known was the need to get some data resources from reques inside, so the first design was as follows: GetEntity (*http. Request) (interface{}, error) returns interface{} because it can represent any type. But this is really not a good design, because for different structures, we need to change the GEThe Tentity function. There's an unwritten rule in the Go language: <font color = "Red" >it ' s typically better to take-in an interface{} value as a parameter than it's To return an interface{} value. (Postel's law, applied to interfaces) </font> or can be designed in this mode: GetUser (*http. Request) (user, error) in this way, each type of user corresponds to a function, although this can be achieved, but it will appear that the code is difficult to form a unified concept. (You can understand that the code is not graceful enough, after all, object-oriented language, if each object has its own function, there is no unified management, then the code readability and maintenance will be very poor), so we can be designed to: type Entity interface {unmarshalhttp (* http. Request) Error}func getentity (R *http. Request, v Entity) error {return v.unmarshalhttp (R)} This way the GetEntity function can receive any type parameter that has a unmarshalhttp function, first declaring a user Point as the receiver's unmarshalhttp function. Func (U *user) unmarshalhttp (R *http. Request) Error {//...} Then we need to declare a user variable and then pass the pointer to the function getentity. var u userif Err: = GetEntity (req, &u); Err! = Nil {//...} So each time you add a type, you simply define its contents and unmarshalhttp function, and then call the Unified function getentity to get the data you want. We just need to focus on the writing of HTTP handlers. The go language and other languages have a different point, when the Var u User, the go language will automatically initialize all the variables, such as User is a struct, then the structure of the data will be initialized, will not cause some language does not initialize the occurrence of chaotic values. # #结束语请记住以下几点: 1. Design should be designed according to the common denominator of the function of the type, and notis based on the common denominator of the data. 2. interface{} is not an arbitrary type, but interface{} type 3. The interface consists of two words, one pointing to the data, and one pointing to the method of table 4. Use interface{} The most parameter ratio as the return value is good 5. A variable is a function of the receiver and can be called with a pointer, but not 6. All variables are passed as arguments, including the receiver of the function 7. A interface variable is not strictly a pointer or a pointer type, it is just a interface8. If you want to completely override a value inside a function, use the * action to dereference the pointer. 182 reads ∙ 1 likes
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.
A Free Trial That Lets You Build Big!
Start building with 50+ products and up to 12 months usage for Elastic Compute Service