This is a creation in Article, where the information may have evolved or changed.
Interface type function, refers to the implementation of the interface with a function, so it is very easy to call, I call this function, the interface type function, this way is used for only one function of the interface.
We demonstrate this technique by iterating over a map, which is a bit like the each method of map in groovy, which is also the gradle each closure.
Original interface Implementation
1234567891011 |
type Interface Interface {})}funceachmap[interface{}]interface{}, H Handler) {ifnillen0 {forrange m {h.do (k, V)}}} |
First define a handler interface, only a Do method, receive the K,v two parameters, this is an interface, we will implement him later, specifically what to do with our implementation of the decision.
Then we define an each function, the function of which is to iterate over the map parameters, and then pass each key and value of the map to the handler do method, to do the specific things, can be output, can also be calculated, This is specifically determined by the implementation of this handler, which is also interface-oriented programming.
Now let's start with the new semester and introduce ourselves as examples, demonstrating the use of the each method and the handler interface we just defined. Here we assume that there are three students: Zhang San, John Doe and Harry, each of whom will introduce their name and age.
12345678910111213141516 |
type welcome string func (W welcome) do (K, v interface {}) {FMT. Printf ( "%s, my name is%s, this year%d years \" , W,k, v)}func main () {persons: = Make (map [interface {}] Interface {}) Persons[ "Zhang San" ] = 20 persons[ "John Doe" ] = 23 persons[ "Harry" ] = 26 var w welcome = "good everyone" each (persons, W)} |
The above implementation, we define a map to store students, map key is the student's name, value is the student's age. welcomeis our newly defined type, corresponding to the basic type string, which welcome implements the handler interface and prints out the self-introduction.
Interface type function appearance
The above implementation, the main two points are not very good:
- Because the handler interface must be implemented, the Do method name cannot be modified, and a more meaningful name cannot be defined.
- You must define a new type to implement the handler interface before you can use the each function
First we solve the first problem, according to what we do to define a more meaningful method name, such as the example of self-introduction, then the use of selfinfo than do this dry method is much better.
If the caller changed the method name, then the handler interface could not be implemented, and what should I do with each method? That is, by providing the implementation of the handler that provides the each function, we add the following code:
12345 |
type funcinterface{}) func (f Handlerfunc) Do interface{}) {f (k,v)} |
The above code, we define a new type Handlerfunc, which is a func (k, v interface{}) type, and then this new Handlerfunc implements the handler interface, the implementation of the Do method is called Handlerfunc itself, Because a variable of type Handlerfunc is a method.
Now we use this approach to achieve the same effect.
1234567891011121314151617 |
type welcome string func (W welcome) selfinfo (K, v interface {}) fmt. Printf ( "%s, my name is%s, this year%d years \" , W,k, v)}func main () {persons: = Make (map [interface {}] Interface {}) Persons[ "Zhang San" ] = 20 persons[ "John Doe" ] = 23 persons[ "Harry" ] = 26 var w welcome = "good everyone" each (persons, Handlerfunc (W.selfinfo) )}
|
or almost the original implementation, just to change the method name do Selfinfo. Is HandlerFunc(w.selfInfo) not a call to a method, but a transformation, because Selfinfo and Handlerfunc are the same type, so you can force the transformation. After the transformation, because Handlerfunc implements the handler interface, we can continue to use the original each method.
Further refactoring
Now that we've solved the problem of naming, but every time a forced transformation is not good, we continue to refactor, and we can use the new definition of a function to help the caller to force the transformation.
123456789101112131415161718192021 |
func eachfunc(M map[interface{}]interface{}, F func( K, v interface{})){each (M,handlerfunc (f))}typeWelcomestring func (w welcome) Selfinfo(k, v interface{}) {FMT. Printf ("%s, my name is%s, this year%d years old \ n", W,k, V)} func main() {Persons: = Make(Map[Interface{}]Interface{}) persons["Zhang San"] = -persons["John Doe"] = atpersons["Harry"] = -varW welcome ="Good for everyone."Eachfunc (Persons, W.selfinfo)} |
A new Eachfunc function is added to help the caller to force the transition, and the caller does not have to do it himself.
Now we find that the Eachfunc function receives a function of the func (K, v interface{}) type, there is no need to implement the handler interface, so our new type can be removed.
12345678910111213 |
func selfinfo Span class= "params" > (K, v interface {}) fmt. Printf ( Hello, my name is%s, this year%d years \ n ", K, v)}func main () {persons: = Make (map [interface {}] Interface {}) Persons[ "Zhang San" ] = 20 persons[ "John Doe" ] = 23 persons[ "Harry" ] = 26 Eachfunc (Persons, Selfinfo)} |
After removing the custom type welcome , the entire code is more concise and more readable. The meaning of our approach is:
- Let the student introduce himself
- Let these students stand up
- Let these students morning reading
- Let these students ...
This is the default, method processing, and more in line with natural language rules.
Extended
The above about the functional interface is finished, if we carefully notice, find and our own usual use of HTTP. The handle method is very much like, in fact, interface http. That's how handler is done.
1234567891011 |
type Interface {servehttp (Responsewriter, *request)} funcHandlestring, Handler handler) {Defaultservemux.handle (pattern, handler)} funchandlefuncstringfunc(Responsewriter, *request)) {Defaultservemux.handlefunc (pattern, handler)} |
This is a very good technique, providing two functions that can be used either as an interface or in a method that corresponds to each and eachfunc in our example, with the flexibility and convenience of the two functions.
Finally, attach the full source code:
1234567891011121314151617181920212223242526272829303132333435363738394041 |
PackageMainImport("FMT")typeHandlerInterface{Do (k, VInterface{})}typeHandlerfunc func(k, v interface{}) func (f Handlerfunc) Do(k, v interface{}){f (k, V)} func each(m map[interface{}]interface{}, H Handler) {ifM! =Nil&&Len(m) >0{ forK, V: =RangeM {h.do (k, V)}}} func eachfunc(M map[interface{}]interface{}, F func( K, v interface{})){each (M, Handlerfunc (f))} func selfinfo(k, v interface{}) {FMT. Printf ("Hello, my name is%s, I'm%d this year \ \", K, V)} func main() {Persons: = Make(Map[Interface{}]Interface{}) persons["Zhang San"] = -persons["John Doe"] = atpersons["Harry"] = -Eachfunc (Persons, Selfinfo)} |