Friday, 13 May 2016

go - Can methods be created for function types?




I know methods can be created for specific types



Example



type MyFunc func() int

func (f MyFunc) eval() int {
return f()
}


func main() {
var randomFunction MyFunc = func() int {
return 1;
}

fmt.Println(randomFunction.eval()) // prints 1
}



But randomFunction had to be declared as with MyFunc type. If the declaration looked like



randomFunction := func() int {
return 1;
}


the method call wouldn't had worked.



My question is whether methods can be created for every function with func () int type, for example.




I know Go is not functional, nor does contain too many functional idioms, but the I'm looking for an approach similar to Haskell's show instance for functions:



instance Show (Int -> Int) where
show op = show "Function with 1 Int param and Int return type"

Answer



Methods are "bound" to a type. MyFunc.eval() is bound to type MyFunc.



This:




randomFunction := func() int {
return 1
}


Is a short variable declaration which creates a variable with name randomFunction and uses a function literal to provide an initial value for it, whose type will be an anonymous function type: func() int. This type does not have the eval() function (anonymous types have zero methods).



But you may use a type conversion to convert it to MyFunc, and the resulting value will have that method:




randomFunction2 := func() int {
return 1
}
fmt.Println(MyFunc(randomFunction2).eval()) // prints 1


The above conversion does not change the type of randomFucntion2 of course.



If you use the conversion in the short variable declaration, randomFunction3 will have a static type of MyFunc and "always" have the eval() method:




randomFunction3 := MyFunc(func() int {
return 1
})
fmt.Println(randomFunction3.eval()) // prints 1


Also note that oftentimes you don't even have to manually convert your function values, as if it is an anonymous type, the conversion will happen automatically.



For example if you have a function that takes a value of type MyFunc:




func handle(f MyFunc) {
fmt.Println(f.eval())
}


You may pass the above randomFunction2 to it:



handle(randomFunction2) // This is OK



The above works because the value of randomFunction2 is assignable to a (variable of) type MyFunc (they have the same base type). For details, see Custom type passed to function as a parameter.



Try the examples on the Go Playground.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...