Method can be created for function type but what is best usecase for this?


(Prithvipal Singh) #1

We can create a type of function as below:

type A func(int, int) int

Also, we can create a method to any type including function type:

func (m myfun) m1() {
	fmt.Println("Hey!!!")
	s := m("Ram", "Shyam")
	fmt.Println(s)
}

We can call m1 method by on variable of myfun type.

func main() {
	var fn myfun
	fn = func(a, b string) string {
		return fmt.Sprintf("Hi %s and %s, How are you", a, b)
	}
	fn.m1()
}

But my question is, What could be the real time example where method to function type will be created?


(Ivan Matmati) #2

Hi,

You will an example here : example
And from the standard lib itself !
I think it’s a good way to aggregate a bunch of functions that need to collaborate without the need of
a shared state (I think it has something to do with fuctional style). It would be better than having an empty struct with methods on it.


(Ali Koyuncu) #3

https://golang.org/pkg/net/http/#HandlerFunc

  // The HandlerFunc type is an adapter to allow the use of
    // ordinary functions as HTTP handlers. If f is a function
    // with the appropriate signature, HandlerFunc(f) is a
    // Handler that calls f.
    type HandlerFunc func(ResponseWriter, *Request)

    // ServeHTTP calls f(w, r).
    func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
      f(w, r)
    }

It enhances polymorphism, I don’t know any language that has methods defined on functions&types :slight_smile: It is one of my favorites features in go, it is really strange but it is beautiful.


(Prithvipal Singh) #4

@imatmati and @ali_koyuncu Thank you very much for wonderful answers with stdlib example :slight_smile:

I have written the code which defines methods on function here(inspired by the example shared by @imatmati)

But I am still wondering, why do we need methods on a function. We can achieve the same by defining a function which expects function as a parameter like https://play.golang.org/p/nZN3b6gryFP.


(Ivan Matmati) #5

Hi,

If you look at Ali’s example, you’ll have an hint of the usefulness of this possibility.
It can be used to transform a function to an other type, that is to say you can build an adapter. You can find further in the source code an example of use of this technique.

func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request)) {
  if handler == nil {
	panic("http: nil handler")
  }
   mux.Handle(pattern, HandlerFunc(handler))
}

You see how it casts a function to an HandlerFunc. And HandlerFunc is only an adpater that serves to call the function given.

Here a more understandable example I created.

// main
package main

import (
"fmt"
)

func doTask(input string) {
  	fmt.Println("task executed with input", input)
}

type TaskAdapter func(string)

func (ta TaskAdapter) job(input string) {
	ta(input)
}

type Task interface {
	job(string)
}

func run(task Task) {
 	task.job("blablabla")
}

func main() {
   run(TaskAdapter(doTask))
}

You see here how you can transform a function in a “structure” implementing an interface needed by a function. Have a nice day.