7

Basically if I have a slice or array of any arbitrary functions, how can I select only the ones that return int, or select only the ones that take ints?

I figured that I would need to use the reflect package, but just reading the docs didn't really help me figure out exactly how to do it.

6
  • See if this thread on golang-nuts helps Commented Sep 17, 2012 at 15:33
  • 1
    can you explain the problem you are trying to solve instead of the solution you are trying to implement? There is likely an easier way to do this in Go. The type of approach you are attempting is very awkward in Go. Depending on what you're trying to do, dystroy's suggestion may be your only option, but there's a very good chance you can do something far less confusing. Commented Sep 17, 2012 at 16:51
  • Nope, what I am trying to do is in fact confusing. Consider creating a graph where each node is a function. I want to search over the space of graphs given an arbitrary list of functions. The idea would be that it can be used as a function approximator ala Machine Learning. I believe that dystroy's solution is what I want. If you want to suggest a language in which it would be nicer I am open to ideas. I have heard that C# could do it. Commented Sep 17, 2012 at 22:11
  • ah, I don't have ML experience to advise, but it sounds like you can get away with either using a function type as a field, e.g. type Node struct { Neighbors []*Node; Fn func(int...) int}, or using a recursive interface like type Node interface { Children []Node; Fn(int...) int }. There's probably a way to avoid reflect that will save you some trouble. Rob Pike's talk "Lexical Scanning in Go" discusses the recursive interface thing. It's very useful. Commented Sep 18, 2012 at 0:31
  • 1
    you were right: that is, in fact, confusing. Anywho, function types can have methods on them in Go, which means that an interface{} value can contain a function type (because a function type still has a method set, even if it is empty). If you define a type Node struct { F interface{} } and stick functions in it, you can make this a little easier to maintain: play.golang.org/p/ANJBr1i8Zh. Cool problem. Commented Sep 18, 2012 at 19:56

1 Answer 1

12

This program prints the functions taking an int as parameter or returning an int :

package main

import (
    "fmt"
    "reflect"
)

func main() {
    funcs := make([]interface{}, 3, 3) // I use interface{} to allow any kind of func
    funcs[0] = func (a int) (int) { return a+1} // good
    funcs[1] = func (a string) (int) { return len(a)} // good
    funcs[2] = func (a string) (string) { return ":("} // bad
    for _, fi := range funcs {
        f := reflect.ValueOf(fi)
        functype := f.Type()
        good := false
        for i:=0; i<functype.NumIn(); i++ {
            if "int"==functype.In(i).String() {
                good = true // yes, there is an int among inputs
                break
            }
        }
        for i:=0; i<functype.NumOut(); i++ {
            if "int"==functype.Out(i).String() {
                good = true // yes, there is an int among outputs
                break
            }
        }
        if good {
            fmt.Println(f)
        }
    }
}

I think the code is self explanatory

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.