英文:
Why can not use Pointer() method when reflect.Value is passed to an interface in golang?
问题
我正在编写一个单元测试来检查包含函数的结构体的相等性。
以下是我的测试代码。
Go Playground
在比较时,我使用了一个名为GetFunctionName的函数来获取函数的名称。
func GetFunctionName(i interface{}) string {
fmt.Printf("type in GetFunctionName: %v\n", reflect.TypeOf(reflect.ValueOf(i)))
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
}
还编写了一个比较函数。
func SelectCompareStruct(got interface{}, want interface{}) {
rvGot := reflect.ValueOf(got)
rtGot := rvGot.Type()
rvWant := reflect.ValueOf(want)
rtWant := rvWant.Type()
for i := 0; i < rtGot.NumField(); i++ {
fieldGot := rtGot.Field(i)
fieldWant := rtWant.Field(i)
valueGot := rvGot.FieldByName(fieldGot.Name)
valueWant := rvWant.FieldByName(fieldWant.Name)
fmt.Printf("type in SelectCompareStruct: %v\n", reflect.TypeOf(reflect.ValueOf(valueGot)))
// Works
gotFuncNameInner := runtime.FuncForPC(valueGot.Pointer()).Name()
wantFuncNameInner := runtime.FuncForPC(valueWant.Pointer()).Name()
fmt.Printf("gotFuncNameInner:\n\t\t\t%v\nwantFuncNameInner:\n\t\t\t%v\n", gotFuncNameInner, wantFuncNameInner)
// Does not work
gotFuncName := GetFunctionName(valueGot)
wantFuncName := GetFunctionName(valueWant)
fmt.Printf("gotFuncName:\n\t%v\n wantFuncName:\n\t%v\n", gotFuncName, wantFuncName)
}
}
你可以看到,当我直接获取函数的名称时,它可以工作。
然而,当我使用一个函数时,它就无法工作了。
尽管两者都是应用了Pointer()方法的reflect.Value类型。
是的,我可以将GetFunctionName的输入类型更改为reflect.Value以使其工作。
但这对其他用例来说并不好。我想要一个可以适用于各种情况的获取名称的函数。
最好能够将输入类型设为interface{}。
有人知道为什么吗?如何修复这个问题?
英文:
I am writing a unit test to check equality of struct that contains func.
Here are my test code.
Go Palyround
When comparing, I used a func named GetFunctionName to get function's name for going.
func GetFunctionName(i interface{}) string {
fmt.Printf("type in GetFunctionName: %v\n", reflect.TypeOf(reflect.ValueOf(i)))
return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
}
Also a compare function was made.
func SelectCompareStruct(got interface{}, want interface{}) {
rvGot := reflect.ValueOf(got)
rtGot := rvGot.Type()
rvWant := reflect.ValueOf(want)
rtWant := rvWant.Type()
for i := 0; i < rtGot.NumField(); i++ {
fieldGot := rtGot.Field(i)
fieldWant := rtWant.Field(i)
valueGot := rvGot.FieldByName(fieldGot.Name)
valueWant := rvWant.FieldByName(fieldWant.Name)
fmt.Printf("type in SelectCompareStruct: %v\n", reflect.TypeOf(reflect.ValueOf(valueGot)))
// Works
gotFuncNameInner := runtime.FuncForPC(valueGot.Pointer()).Name()
wantFuncNameInner := runtime.FuncForPC(valueWant.Pointer()).Name()
fmt.Printf("gotFuncNameInner:\n\t\t\t%v\nwantFuncNameInner:\n\t\t\t%v\n", gotFuncNameInner, wantFuncNameInner)
// Does not work
gotFuncName := GetFunctionName(valueGot)
wantFuncName := GetFunctionName(valueWant)
fmt.Printf("gotFuncName:\n\t%v\n wantFuncName:\n\t%v\n", gotFuncName, wantFuncName)
}
}
You can see, when I write directly to get function's name, it works.
However, it does not work when using a func instead.
Although, both of which type that apply Pointer() method are reflect.Value type.
Yes, I can change input type of GetFunctionName to reflect.Value for working.
That's not good for other use cases. I want to make a function for getting name for versatility.
It will be beautiful to make input type interface{}.
Anyone have any idea why? And how to fix it?
答案1
得分: 1
问题是你在 reflect.Value 上调用了 reflect.Value。通过删除对 reflect.Value 的额外调用来修复。
func GetFunctionName(v reflect.Value) string {
fmt.Printf("type in GetFunctionName: %v\n", v.Type())
return runtime.FuncForPC(v.Pointer()).Name()
}
在 playground 上运行它:点击这里。
英文:
The problem is that you are calling reflect.Value on a reflect.Value. Fix by removing the extra call to reflect.Value.
func GetFunctionName(v reflect.Value) string {
fmt.Printf("type in GetFunctionName: %v\n", v.Type())
return runtime.FuncForPC(v.Pointer()).Name()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论