Can functions be passed as parameters?

FunctionGo

Function Problem Overview


In Java I can do something like

derp(new Runnable { public void run () { /* run this sometime later */ } })

and "run" the code in the method later. It's a pain to handle (anonymous inner class), but it can be done.

Does Go have something that can facilitate a function/callback being passed in as a parameter?

Function Solutions


Solution 1 - Function

Yes, consider some of these examples:

package main

import "fmt"

// convert types take an int and return a string value.
type convert func(int) string

// value implements convert, returning x as string.
func value(x int) string {
    return fmt.Sprintf("%v", x)
}

// quote123 passes 123 to convert func and returns quoted string.
func quote123(fn convert) string {
    return fmt.Sprintf("%q", fn(123))
}

func main() {
    var result string
    
    result = value(123)
    fmt.Println(result)
    // Output: 123
    
    result = quote123(value)
    fmt.Println(result)
    // Output: "123"
    
    result = quote123(func(x int) string { return fmt.Sprintf("%b", x) })
    fmt.Println(result)
    // Output: "1111011"
    
    foo := func(x int) string { return "foo" }
    result = quote123(foo)
    fmt.Println(result)
    // Output: "foo"
    
    _ = convert(foo) // confirm foo satisfies convert at runtime
    
    // fails due to argument type
    // _ = convert(func(x float64) string { return "" })
}

Play: http://play.golang.org/p/XNMtrDUDS0

Tour: https://tour.golang.org/moretypes/25 (Function Closures)

Solution 2 - Function

You can pass function as parameter to a Go function. Here is an example of passing function as parameter to another Go function:

package main

import "fmt"

type fn func(int) 

func myfn1(i int) {
	fmt.Printf("\ni is %v", i)
}
func myfn2(i int) {
	fmt.Printf("\ni is %v", i)
}
func test(f fn, val int) {
	f(val)
}
func main() {
	test(myfn1, 123)
	test(myfn2, 321)
}

You can try this out at: https://play.golang.org/p/9mAOUWGp0k

Solution 3 - Function

Here is the sample "Map" implementation in Go. Hope this helps!!

func square(num int) int {
	return num * num
}

func mapper(f func(int) int, alist []int) []int {
	var a = make([]int, len(alist), len(alist))
	for index, val := range alist {

		a[index] = f(val)
	}
	return a
}

func main() {
	alist := []int{4, 5, 6, 7}
	result := mapper(square, alist)
	fmt.Println(result)

}

Solution 4 - Function

Here is a simple example:

    package main

    import "fmt"

    func plusTwo() (func(v int) (int)) {
	    return func(v int) (int) {
		    return v+2
	    }
    }

    func plusX(x int) (func(v int) (int)) {
	   return func(v int) (int) {
           return v+x
	   }
    }

    func main() {
	    p := plusTwo()
	    fmt.Printf("3+2: %d\n", p(3))

	    px := plusX(3)
	    fmt.Printf("3+3: %d\n", px(3))
    }

Solution 5 - Function

This is the simplest way I can come with.

package main

import "fmt"

func main() {
    g := greeting
    getFunc(g)
}

func getFunc(f func()) {
    f()
}

func greeting() {
    fmt.Println("Hello")
}

Solution 6 - Function

I hope the below example will provide more clarity.

package main

type EmployeeManager struct{
	category 			string
	city				string
	calculateSalary 	func() int64
}


func NewEmployeeManager() (*EmployeeManager,error){

	return &EmployeeManager{
		category : "MANAGEMENT",
		city : "NY",
		calculateSalary: func() int64 {
			var calculatedSalary int64
			// some formula
			return calculatedSalary
		},
	},nil
}

func (self *EmployeeManager) emWithSalaryCalculation(){
	self.calculateSalary = func() int64 {
		var calculatedSalary int64
		// some new formula
		return calculatedSalary
	}
}

func updateEmployeeInfo(em EmployeeManager){
	// Some code
}

func processEmployee(){
	updateEmployeeInfo(struct {
		category        string
		city            string
		calculateSalary func() int64
	}{category: "", city: "", calculateSalary: func() int64 {
		var calculatedSalary int64
		// some new formula
		return calculatedSalary
	}})
}

Solution 7 - Function

You can also pass the function of a struct, like:

    package main
    // define struct
    type Apple struct {}
    
    // return apple's color
    func (Apple) GetColor() string {
         return "Red" 
    }
    
    func main () {
    	// instantiate
    	myApple := Apple{}
    	
        // put the func in a variable
    	theFunc := myApple.GetColor
    	
        // execute the variable as a function
    	color := theFunc()
    
    	print(color)
    }

output will be "Red", check on the playground

Solution 8 - Function

Yes Go does accept first-class functions.

See the article "First Class Functions in Go" for useful links.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSaadView Question on Stackoverflow
Solution 1 - FunctiondskinnerView Answer on Stackoverflow
Solution 2 - FunctionSeattleOrBayAreaView Answer on Stackoverflow
Solution 3 - Functionrobus gauliView Answer on Stackoverflow
Solution 4 - FunctionfoamdinoView Answer on Stackoverflow
Solution 5 - FunctionTushar GhigeView Answer on Stackoverflow
Solution 6 - FunctionCodeAdocateView Answer on Stackoverflow
Solution 7 - FunctionAmin ShojaeiView Answer on Stackoverflow
Solution 8 - FunctionAbdulFattah PopoolaView Answer on Stackoverflow