You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang如何自动收集interface的所有实现并填充到slice中

方案1:init 函数全局注册(最常用,无额外依赖)

这是Go生态最通用的插件注册模式,无需硬编码切片,新增插件仅需补充注册逻辑,不需要修改主程序代码。

实现步骤

  1. 定义全局注册列表和注册函数
package main

import "fmt"

type Plugin interface {
    Run() bool
}

// 全局存储所有已注册的插件
var pluginRegistry []Plugin

// 注册插件的公共方法,供插件实现侧调用
func RegisterPlugin(p Plugin) {
    pluginRegistry = append(pluginRegistry, p)
}
  1. 每个插件实现侧添加init函数自动注册
// Plugin1 实现
type Plugin1 struct{}
func (p Plugin1) Run() bool {
    fmt.Println("Plugin1::Run()")
    return true
}
// 包初始化时自动注册插件
func init() {
    RegisterPlugin(Plugin1{})
}

// Plugin2 实现
type Plugin2 struct{}
func (p Plugin2) Run() bool {
    fmt.Println("Plugin2::Run()")
    return true
}
func init() {
    RegisterPlugin(Plugin2{})
}
  1. 主程序直接使用注册列表,无需硬编码切片
func main() {
    for _, plugin := range pluginRegistry {
        plugin.Run()
    }
}

方案2:代码自动生成

如果不想依赖init函数执行逻辑,可以通过go generate实现静态生成切片:

  • 编写小工具扫描当前项目下所有实现了Plugin接口的结构体
  • 工具自动生成plugins_gen.go文件,内容为自动拼接的插件切片定义
  • 在代码中添加//go:generate go run 你的生成工具路径注释,每次新增插件后执行go generate即可自动更新切片

方案3:动态加载插件

如果需要插件独立于主程序编译、支持热插拔,可以使用Go标准库的plugin包:

  • 每个插件单独编译为.so动态链接库
  • 主程序启动时扫描指定目录下的所有.so文件,动态加载后查找导出的插件实例,转为Plugin接口加入调用列表
  • 注意:plugin包仅支持Unix-like系统,且主程序和插件的编译环境、依赖版本必须完全一致,否则会加载失败。

内容的提问来源于stack exchange,提问作者daisy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 09:24:03