2

Is it possible in GO to find structs or functions by criteria such as name, tag or interface? i.e something along the lines of command line tasks/verbs? i.e:

func cmd1() {
    ...
}

func cmd2() {
    ...
}

...

func cmdN() {
}

func main() {
    // Inspect os.Args and call cmd{X}() based on args.
    ...
}

I don't mind what the exact mechanism is and if the final targets are functions or structs - the goal is to get something working by convention without any boilerplate code.

Amir Abiri
  • 8,847
  • 11
  • 41
  • 57

2 Answers2

1

You could use reflection

package main

import (
    "flag"
    "fmt"
    "reflect"
)

var cmd command

type command struct{}

func (c command) execute(name string) {
    v := reflect.ValueOf(c)

    cmd := v.MethodByName(name)
    if !cmd.IsValid() {
        fmt.Println(name + " not a command")
        return
    }

    cmd.Call([]reflect.Value{})
}

func (c command) Cmd1() {
    fmt.Println("command 1")
}

func (c command) Cmd2() {
    fmt.Println("command 2")
}

func (c command) Cmd3() {
    fmt.Println("command 3")
}

func main() {
    flag.Parse()

    cmd.execute(flag.Arg(0))
}

or you could use a map.

package main

import (
    "flag"
    "fmt"
)

func cmd1() {
    fmt.Println("command 1")
}

func cmd2() {
    fmt.Println("command 2")
}

func cmd3() {
    fmt.Println("command 3")
}

var funcs = map[string]func(){
    "cmd1": cmd1,
    "cmd2": cmd2,
    "cmd3": cmd3,
}

func main() {
    flag.Parse()

    if f, ok := funcs[flag.Arg(0)]; ok {
        f()
    } else {
        fmt.Println(flag.Arg(0) + " command not found")
    }
}
jmaloney
  • 11,580
  • 2
  • 36
  • 29
0

I used a similar approach in "How to test a collection of functions by reflection in Go?"

The idea is to list and find all the functions needed, in my case, functions for a certain struct type:

stype := reflect.ValueOf(s)
for _, fname := range funcNames {
    sfunc := stype.MethodByName(fname)
    // no parameter => empty slice of Value
    ret := sfunc.Call([]reflect.Value{})
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Sorry - just realised your solution also requires knowing the methods up front. Basically this isn't doable in Go... https://groups.google.com/forum/#!topic/golang-nuts/M0ORoEU115o – Amir Abiri Sep 27 '14 at 18:16