function - 在不调用函数的情况下,如何判断一个类型的基函数是否已在 Go 中被覆盖?
问题描述
我在 Go 中实现了一个简单的路由器。当没有为该端点实现调用的方法时,我曾经为每个端点返回错误的大量冗余代码。我重构并创建了一个“基本”类型,它为每个请求类型提供默认函数,这些函数只返回未实现的错误。现在我所要做的就是覆盖我希望实现的给定端点的特定方法函数。这一切都很有趣和游戏,直到我想弄清楚,给定一个端点变量,哪些方法已被覆盖?
省略无关的细节,这是我现在能想到的一个简单的例子:
package main
import (
"fmt"
)
// Route defines the HTTP method handlers.
type Route interface {
Get() string
Post() string
}
// BaseRoute is the "fallback" handlers,
// if those handlers aren't defined later.
type BaseRoute struct{}
func (BaseRoute) Get() string {
return "base get"
}
func (BaseRoute) Post() string {
return "base post"
}
// Endpoint holds a route for handling the HTTP request,
// and some other metadata related to that request.
type Endpoint struct {
BaseRoute
URI string
}
// myEndpoint is an example endpoint implementation
// which only implements a GET request.
type myEndpoint Endpoint
func (myEndpoint) Get() string {
return "myEndpoint get"
}
func main() {
myEndpointInstance := myEndpoint{URI: "/myEndpoint"}
fmt.Println(myEndpointInstance.URI)
fmt.Println(myEndpointInstance.Get())
fmt.Println(myEndpointInstance.Post())
}
此代码段将打印出以下内容:
/myEndpoint
myEndpoint get
base post
所以我对函数的覆盖按预期工作。现在我想知道在我的主函数中,在我声明了 myEndpointInstance 之后,我能否以某种方式告诉 Post 函数没有被覆盖并且仍然由底层 BaseRoute 实现而没有实际调用该函数?理想情况下,我想要这样的东西:
func main() {
myEndpointInstance := myEndpoint{URI: "/myEndpoint"}
if myEndpointInstace.Post != BaseRoute.Post {
// do something
}
}
我已经玩过反射包,但没有发现任何有用的东西。
解决方案
正如其他人所指出的,调用哪个方法是编译时决定的。因此,您可以在编译时检查这一点,大多数 IDE 会将您导航到绑定到实际调用的方法。
如果你想在运行时检查这个,你可以比较函数指针。您无法比较函数值,它们不可比较(仅与nil
值)。规范:比较运算符:
切片、映射和函数值不可比较。但是,作为一种特殊情况,可以将切片、映射或函数值与预先声明的标识符进行比较
nil
。
您可以这样做:
myEndpointInstance := myEndpoint{URI: "/myEndpoint"}
v1 := reflect.ValueOf(myEndpointInstance.Post).Pointer()
v2 := reflect.ValueOf(myEndpointInstance.BaseRoute.Post).Pointer()
fmt.Println(v1, v2, v1 == v2)
v1 = reflect.ValueOf(myEndpointInstance.Get).Pointer()
v2 = reflect.ValueOf(myEndpointInstance.BaseRoute.Get).Pointer()
fmt.Println(v1, v2, v1 == v2)
这将输出(在Go Playground上尝试):
882848 882848 true
882880 882912 false
输出告诉Post()
不是“覆盖”(myEndpointInstance.Post
与 相同myEndpointInstance.BaseRoute.Post
),Get()
而是(myEndpointInstance.Get
与 不同myEndpointInstance.BaseRoute.Get
)。
查看相关问题:
推荐阅读
- c# - 如何在反序列化c#中检查对象是否已更改属性
- javascript - 在反应中发出从一个类到另一个类的发送值
- php - 动态获取PHP中最后一个公共数组值
- jquery - postgres中的时间戳比较
- excel - EXCEL:是否有类似 LOOKUP 的函数/方式,但将数组作为输入并返回数组作为结果
- wordpress - 如何解决错误:警告 call_user_func_array() C...\wp-includes\class-wp-hook.php?
- node.js - 从 Firebase Cloud Functions 将数据发送回 Android
- sql - ORACLE:使用具有关系的两个表更新查询
- python - TKinter 几何管理器显示多行小部件
- javascript - 如何在成功提交表单时重置 ReCaptcha 框