如何修复GO插件中函数的代码文档问题(Golang)

如何修复GO插件中函数的代码文档问题(Golang) 对于普通的Go代码,文档的编写方式如此处所述:

要为类型、变量、常量、函数甚至包编写文档, 只需在其声明前直接写一个常规注释,中间不要有空行。 Godoc 随后会将该注释作为文本与该文档项一同展示。

示例:

// Fprint 使用其操作数的默认格式进行格式化并写入 w。
// 当操作数都不是字符串时,会在操作数之间添加空格。
// 它返回写入的字节数和遇到的任何写入错误。
func Fprint(w io.Writer, a ...interface{}) (n int, err error) { }

我使用插件编写了以下代码:

//file: ./plugin/plugin.go
package main

import "fmt"

var V int

func F() {
	fmt.Printf("Hello, number %d\n", V)
}

// A test plugin function to Return double the entery
func Fx(x int) int {
	return x * 2
}

// Compile as: $ go build -buildmode=plugin

将其编译为插件,并从主代码中调用:

// file main.go
package main

import (
	"plugin"
)

func main() {
	p, _ := plugin.Open("./plugin/plugin.so") // use rela path with code runner: /Users/hasan/goApps/mod/plugin/plugin.so

	v, _ := p.Lookup("V")

	f, _ := p.Lookup("F")

	fx, _ := p.Lookup("Fx")

	*v.(*int) = 7    // .(symbol signature) => (*int)
	f.(func())()   // .(symbol signature) => func() { }

	num := fx.(func(int) int)(3).  // .(symbol signature) => func(int) int { }
	println(num)
}

// Run as $ go run .

插件按预期工作,并显示以下输出:

hasan@Hasans-MacBook-Air goApps % go run .
Hello, number 7
6

但是文档没有显示出来,当我在我的 IDE(VS Code)中将鼠标悬停在 main.go 中每一行出现的 fx 上时,没有任何内容显示。


更多关于如何修复GO插件中函数的代码文档问题(Golang)的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于如何修复GO插件中函数的代码文档问题(Golang)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go插件中,函数文档无法通过标准godoc工具或IDE悬停显示,因为插件是运行时动态加载的二进制文件,不包含源码级别的文档注释信息。插件符号的文档需要通过其他方式获取。

以下是解决方案示例:

// 方案1:在插件包中创建独立的文档函数
package main

import "fmt"

// PluginDoc 返回插件的文档映射
func PluginDoc() map[string]string {
    return map[string]string{
        "V":  "导出的整型变量",
        "F":  "打印问候信息的函数",
        "Fx": "返回输入值两倍的函数,参数:x int,返回值:int",
    }
}

var V int

func F() {
    fmt.Printf("Hello, number %d\n", V)
}

func Fx(x int) int {
    return x * 2
}

主程序中使用:

package main

import (
    "fmt"
    "plugin"
)

func main() {
    p, _ := plugin.Open("./plugin/plugin.so")
    
    // 获取文档
    docFunc, _ := p.Lookup("PluginDoc")
    if docFunc != nil {
        docs := docFunc.(func() map[string]string)()
        fmt.Printf("Fx文档: %s\n", docs["Fx"])
    }
    
    // 使用插件函数
    fx, _ := p.Lookup("Fx")
    num := fx.(func(int) int)(3)
    println(num)
}
// 方案2:使用结构体封装并提供文档方法
package main

import "fmt"

type PluginAPI struct{}

func (p *PluginAPI) Doc() string {
    return `插件API文档:
    V: 整型变量
    F(): 打印函数
    Fx(x int): 返回x*2`
}

func (p *PluginAPI) F() {
    fmt.Printf("Hello, number %d\n", V)
}

func (p *PluginAPI) Fx(x int) int {
    return x * 2
}

var V int
var API = &PluginAPI{}

主程序中使用:

package main

import (
    "fmt"
    "plugin"
)

func main() {
    p, _ := plugin.Open("./plugin/plugin.so")
    
    api, _ := p.Lookup("API")
    if api != nil {
        pluginAPI := api.(interface {
            Doc() string
            F()
            Fx(int) int
        })
        
        fmt.Println(pluginAPI.Doc())
        pluginAPI.F()
        result := pluginAPI.Fx(3)
        println(result)
    }
}
// 方案3:使用JSON文档文件(推荐用于复杂插件)
// plugin/docs.json
{
    "version": "1.0",
    "functions": {
        "Fx": {
            "description": "返回输入值的两倍",
            "signature": "func(int) int",
            "parameters": [
                {"name": "x", "type": "int", "description": "输入数值"}
            ],
            "returns": "int"
        }
    }
}

插件中嵌入文档:

package main

import _ "embed"

//go:embed docs.json
var pluginDocs string

func GetDocs() string {
    return pluginDocs
}

// ... 其他插件代码

这些方案通过编程方式提供文档,弥补了插件系统缺乏源码级文档支持的不足。

回到顶部