-3

I am trying to make middleware to my functions similar to the pattern used for http.HandlerFunc, this usually works:

func middleware(fn http.HandlerFunc) http.HandlerFunc {
    return func (wr http.ResponseWriter, r *http.Request) {
        fmt.Println("doing something before")
        fn(wr, r)
    }
}

func main() {
    middleware(func (wr http.ResponseWriter, r *http.Request) {
        wr.Write([]byte("..."))
    })
}

This doesn't work:

package main

import (
    "fmt"
)

type FN func (arg int)

func myFunc(arg int) {
    fmt.Println("Arg:",arg)
}
// Logically here I am returning the function not it's value
// http package does this identically, I don't see the difference
func do(fn FN) FN {
    return func (arg int) {
        fn(arg)
    }
}

func main() {
    do(myFunc(3))
}

Will return compile error: myFunc(3) used as value

As you can see here: https://golang.org/src/net/http/server.go?s=64103:64150#L2055

On line 2065:

// 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)

This function signature also does not return a value yet this compiles.

UPDATE:

This pattern is what I was trying to achieve, which now works.

package main

import (
 "fmt"
)

type FN func (arg int)
func do(fn FN) FN {
    return func (arg int) {
    fmt.Println("executed do with arg",arg)
    // some other code ...
    fn(arg) // call wrapped function
   }
}
func something(arg int){
fmt.Println("Executed something with arg",arg)
}

func main() {
   do(something)(3)
}

Output:

executed do with arg 3
Executed something with arg 3

Program exited.
Mihai
  • 82
  • 1
  • 6
  • 1
    `myFunc` returns nothing. But you're calling it in a context where its return value is needed. This is what the error means. – Jonathan Hall Feb 18 '21 at 09:32
  • Possible duplicates: https://stackoverflow.com/q/12561162/13860, https://stackoverflow.com/questions/16596805/function-used-as-value-compile-error – Jonathan Hall Feb 18 '21 at 09:34
  • @Flimzy But as far as I can see func (wr http.ResponseWriter, r *http.Request) {} also doesn't return any value – Mihai Feb 18 '21 at 09:35
  • 3
    But you're not calling that function in a context where a return value is expected. – Jonathan Hall Feb 18 '21 at 09:36

1 Answers1

2

You are using myFunc(arg int) - which doesn't return anything, and trying to pass it's return value into do. It looks like maybe you want to do:

func main() {
    do(myFunc)(3)
}

but not really sure

dave
  • 62,300
  • 5
  • 72
  • 93