如何编写一个包装库的 Go 包,以便调用被覆盖的函数使用我的实现,而非覆盖函数“落入”我正在包装的库?
特别是:我希望我的 Go 包 wrap net/http
,除了我最初只想替换http.FileServer
and http.NotFoundHandler
,并让所有其他功能保持不变。我的库是现有代码的替代品,它调用了net/http
我不会覆盖的其他函数。例如,我希望能够做到:
package main
import (
"log"
http "github.com/jstrieb/my-special-http-lib"
)
func main() {
http.ListenAndServe( // Use the net/http ListenAndServe by "falling through" my library
":8080",
http.FileServer(http.Dir("/usr/share/doc")) // Use my custom, overridden http.FileServer
)
}
我试过的
我可以手动覆盖包装库导出的每个函数(如下所示),但如果可能的话,我宁愿避免这种情况。这种方法是不可取的,因为它不考虑从我包装的库中调用我覆盖的函数的实例。
func ExportedFunction(input1 type1) type2 {
return http.ExportedFunction(input1)
}
我也可以完全分叉net/http
源并直接更改它,但我希望清楚我正在做哪些更改,而无需与原始版本进行比较。维护标准库的一部分以仅覆盖几个函数也是没有意义的。
理由
我不是在寻找关于这是否是一个“好”想法的评论。我只是想知道该怎么做。
这个库的计划是简单地改变 404 页面和目录列表索引页面的外观。这种纯粹的美学变化不会影响net/http
. 如果它的结构不是包装所有的net/http
,那么用户将不得不在使用两个包之间切换来做同样的事情。那么我的库不能被认为是已经使用net/http
.
随着时间的推移,我还打算覆盖更多函数,但我的库的 API 将始终与net/http
. 这样做可以减少每次库更改时手动http.Function
替换调用的需要。mylibrary.Function
此外,我希望能够在net/http
我没有编写的代码(使用)中导入我的替换,并且不想手动重构。