golang实现反射动态调用

# 目录

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
your_project
├── go.mod
├── invoker
│   └── invoker.go
├── main.go
├── packageA
│   └── packageA.go
├── packageB
│   └── packageB.go
└── registry
    └── registry.go

# 具体代码

  • go.mod
1
2
3
module your_project

go 1.18
  • invoker.go
1
2
3
4
5
package invoker

type Invoker interface {
	Invoke(args ...interface{}) (interface{}, error)
}
  • main.go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package main

import (
	"fmt"
	_ "your_project/packageA"
	_ "your_project/packageB"
	"your_project/registry"
)

func main() {
	for _, v := range registry.GetRegistryList() {
		instance, _ := registry.Get(v)
		result, _ := instance.Invoke()
		fmt.Println(result)
	}
}

func init() {
	fmt.Println("main.init")
}
  • packageA.go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package packageA

import (
	"fmt"
	"your_project/invoker"
	"your_project/registry"
)

func init() {
	fmt.Println("packageA init")
	registry.Register("packageA", NewPackageA)
}

type PackageA struct{}

func (p *PackageA) Invoke(args ...interface{}) (interface{}, error) {
	return "Hello from PackageA", nil
}

func NewPackageA() invoker.Invoker {
	return &PackageA{}
}
  • packageB.go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
package packageB

import (
	"fmt"
	"your_project/invoker"
	"your_project/registry"
)

func init() {
	fmt.Println("packageB init")
	registry.Register("packageB", NewPackageB)
}

type PackageB struct{}

func (p *PackageB) Invoke(args ...interface{}) (interface{}, error) {
	return "Hello from PackageB", nil
}

func NewPackageB() invoker.Invoker {
	return &PackageB{}
}
  • registry.go
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package registry

import "your_project/invoker"

var registry = make(map[string]func() invoker.Invoker)

func Register(name string, factory func() invoker.Invoker) {
	registry[name] = factory
}

func Get(name string) (invoker.Invoker, bool) {
	factory, ok := registry[name]
	if !ok {
		return nil, false
	}
	return factory(), true
}

func GetRegistryList() []string {
	registryList := make([]string, 0)
	for k := range registry {
		registryList = append(registryList, k)
	}
	return registryList
}

# 运行

1
go run main.go
Licensed under CC BY-NC-SA 4.0