lundi 16 mai 2016

Golang Passing Function Arguments with Arbitrary Interfaces

The following code works nicely:

package main

import (
    "fmt"
)

func WrapperFunc(fn func(int,int) int) int{
    return fn(3,4)
}

func add(a,b int) int{
    return a + b
}

func main(){
    fmt.Println(WrapperFunc(add))
}

I want to pass additional parameters that implements a specific interface. For instance, I modify the code as follows:

import (
    "fmt"
)

type RequestBody interface {
    GetDescription() string
}

type LoginRequest struct {
    Username string
    Password string
}

func (lr LoginRequest) GetDescription() string{
    return "cool function"
}

func WrapperFunc(fn func(int, int, RequestBody) int) int {
    lr := LoginRequest{}
    return fn(3, 4, lr)
}

func add(a, b int, lr LoginRequest) int {
    fmt.Println(lr.GetDescription())
    return a + b
}

func main() {
    fmt.Println(WrapperFunc(add))
}

It fails with the error below:

cannot use add (type func(int, int, LoginRequest) int) as type func(int, int, RequestBody) int in argument to WrapperFunc

However, when I do not implement the GetDescription as below:

package main

import (
    "fmt"
)

type RequestBody interface {
    GetDescription() string
}

type LoginRequest struct {
    Username string
    Password string
}

func WrapperFunc(fn func(int, int, RequestBody) int) int {
    lr := LoginRequest{}
    return fn(3, 4, lr)
}

func add(a, b int, lr LoginRequest) int {
    return a + b
}

func main() {
    fmt.Println(WrapperFunc(add))
}

It fails with second error, as interface is not implemented (as expected).

cannot use lr (type LoginRequest) as type RequestBody in argument to fn:
    LoginRequest does not implement RequestBody (missing GetDescription method)
 cannot use add (type func(int, int, LoginRequest) int) as type func(int, int, RequestBody) int in argument to WrapperFunc

So, it understands that, in WrapperFunc body, I can only call fn with int, int and an RequestBody interface that implements the GetDescription, yet I still cannot pass it in the function phase. How can I accomplish this? I want to wrap functions that can have parameters that their type can change.





Aucun commentaire:

Enregistrer un commentaire