7

time.AfterFunc() accepts a duration and a function to be executed when that duration has expired. But the function cannot be a function that accepts parameters.

For example: The following function cannot be passed:

func Foo (b *Bar) {}

Although, it is possible to initialize a new function that calls the above one and then pass it:

f := func() {
    Foo(somebar)
}
timer := time.AfterFunc(1*time.Second, f)

Should this really be done this way?
Why does time.AfterFunc not accept any functions that accept parameters?
Do there exist other/better ways to do this?

sieberts
  • 528
  • 6
  • 15
  • 3
    No, a closure is fine here. – Volker Apr 03 '18 at 09:19
  • 1
    Since you can't pass additional arguments to `time.AfterFunc()`, how would it "guess" the values of the additional parameters if the function would require any? Alternative to passing a closure, you may also mass a method value ([example1](https://stackoverflow.com/questions/38897529/golang-pass-method-to-function/38897667#38897667), [example2](https://stackoverflow.com/questions/28251283/golang-function-alias-on-method-receiver/28252088#28252088)). – icza Apr 03 '18 at 11:31
  • 1
    a good explanation, why don't you add it as answer?. This is what i wanted to know. – sieberts Apr 04 '18 at 14:14
  • 1
    Why the downvotes? I just started learning Go and found this question helpful. – user_ Apr 07 '18 at 19:11
  • Same question. Why the downvotes? I think stackoverflow should require downvoters to explain, and reveal their identity. It is annoying. – Curious2learn Aug 22 '18 at 14:44

2 Answers2

10

Create a function from the argument, return it.

package main

import (
    "fmt"
    "time"
)

func foo(bar string) {
    fmt.Printf("in foo('%s')\n", bar)
}

func newFunc(bar string) func() {
    fmt.Printf("creating func with '%s'\n", bar)
    return func() {
        foo(bar)
    }
}

func main() {
    somebar := "Here we go!"
    f := newFunc(somebar)
    _ = time.AfterFunc(1*time.Second, f)

    time.Sleep(2 * time.Second)
}

https://play.golang.com/p/lWgeHvPLg9N

3

Anonymous function helps you to send functions with parameters to AfterFunc.

package main

import (
    "fmt"
    "time"
)

func foo(bar string) {

    fmt.Printf("in foo('%s')\n", bar)
}

func main() {
    somebar := "Here we go!"
    time.AfterFunc(1*time.Second, func(){foo(somebar)})
    time.Sleep(2 * time.Second)
}

https://play.golang.com/p/sdpiBtBWt_s

Nashenas
  • 31
  • 2