英文:
Reflection type does not have method
问题
我正在使用Go语言中的反射。为什么这段代码没有列出方法?它只列出了字段。
问题出在这里吗?value interface{} 我不确定如何将一个通用的结构体/类/类型传递给函数。通常我只会传递一个对象。
(我完全是新手。我是一名C#程序员)
package main
import (
	"fmt"
	"reflect"
)
func main() {
	var B TestType = TestType{TestString: "Hello", TestNumber: 3}
	ListMethods(B)
}
func ListMethods(value interface{}) {
	fooType := reflect.TypeOf(value)
	for i := 0; i < fooType.NumMethod(); i++ {
		method := fooType.Method(i)
		fmt.Println("Method = " + method.Name)
	}
	for i := 0; i < fooType.NumField(); i++ {
		field := fooType.Field(i)
		fmt.Println("Field = " + field.Name)
		fmt.Println(reflect.ValueOf(value).Field(i))
	}
}
type TestType struct {
	TestString string
	TestNumber int
}
func (this *TestType) TestFunction() {
	fmt.Println("Test")
}
这段代码没有列出方法,是因为你的TestFunction方法是一个指针接收器方法,而你传递给ListMethods函数的值是一个值类型。要解决这个问题,你可以将ListMethods函数的参数类型改为指针类型,或者将TestType的实例化改为指针类型。
以下是修改后的代码:
package main
import (
	"fmt"
	"reflect"
)
func main() {
	var B TestType = TestType{TestString: "Hello", TestNumber: 3}
	ListMethods(&B)
}
func ListMethods(value interface{}) {
	fooType := reflect.TypeOf(value)
	for i := 0; i < fooType.NumMethod(); i++ {
		method := fooType.Method(i)
		fmt.Println("Method = " + method.Name)
	}
	for i := 0; i < fooType.NumField(); i++ {
		field := fooType.Field(i)
		fmt.Println("Field = " + field.Name)
		fmt.Println(reflect.ValueOf(value).Field(i))
	}
}
type TestType struct {
	TestString string
	TestNumber int
}
func (this *TestType) TestFunction() {
	fmt.Println("Test")
}
这样修改后,你应该能够正确地列出TestType的方法。
英文:
I'm trying to use reflection in Go. Why doesn't this code list the methods? It lists the fields.
is this the problem? value interface{} I'm not sure how to pass a generic struct/class/type to a function. Normally I would just pass an Object.
(I'm totally new at this. I'm a C# programmer)
package main
import (
"fmt"
"reflect"
)
func main() {
    var B TestType = TestType{TestString: "Hello", TestNumber: 3}
    ListMethods(B)
}
func ListMethods(value interface{}) {
    fooType := reflect.TypeOf(value)
	for i := 0; i < fooType.NumMethod(); i++ {
    	method := fooType.Method(i)
	    fmt.Println("Method = " + method.Name)
	}
    for i := 0; i < fooType.NumField(); i++ {
	    field := fooType.Field(i)
	    fmt.Println("Field = " + field.Name)
	    fmt.Println(reflect.ValueOf(value).Field(i))
    }
}
type TestType struct {
    TestString string
    TestNumber int
}
func (this *TestType) TestFunction() {
    fmt.Println("Test")
}
答案1
得分: 3
因为你传递了一个类型,并声明了一个方法来操作该类型的指针。
请看一下这个扩展自你的示例的例子:
package main
import (
	"fmt"
	"reflect"
)
func main() {
	var B TestType = TestType{TestString: "Hello", TestNumber: 3}
	ListMethods(B)
}
func ListMethods(value interface{}) {
	fooType := reflect.TypeOf(value)
	ptrFooType := reflect.PtrTo(fooType)
	for i := 0; i < fooType.NumMethod(); i++ {
		method := fooType.Method(i)
		fmt.Println("Method = " + method.Name)
	}
	for i := 0; i < ptrFooType.NumMethod(); i++ {
		method := ptrFooType.Method(i)
		fmt.Println("* Method = " + method.Name)
	}
	for i := 0; i < fooType.NumField(); i++ {
		field := fooType.Field(i)
		fmt.Println("Field = " + field.Name)
		fmt.Println(reflect.ValueOf(value).Field(i))
	}
}
type TestType struct {
	TestString string
	TestNumber int
}
func (this *TestType) TestFunctionPtr() {
	fmt.Println("Test")
}
func (this TestType) TestFunction() {
	fmt.Println("Test Non Ptr")
}
注意,*Type 可以访问 Type 的方法,但 Type 无法访问 *Type 的方法。
要将 Type 转换为 *Type,我使用了 reflect.PtrTo(Type)。
英文:
Because you are passing a type and you declared a method to the pointer of the type.
https://play.golang.org/p/B0NdVyxGxt
Look at this example extended from yours:
package main
import (
	"fmt"
	"reflect"
)
func main() {
	var B TestType = TestType{TestString: "Hello", TestNumber: 3}
	ListMethods(B)
}
func ListMethods(value interface{}) {
	fooType := reflect.TypeOf(value)
	ptrFooType := reflect.PtrTo(fooType)
	for i := 0; i < fooType.NumMethod(); i++ {
		method := fooType.Method(i)
		fmt.Println("Method = " + method.Name)
	}
	for i := 0; i < ptrFooType.NumMethod(); i++ {
		method := ptrFooType.Method(i)
		fmt.Println("* Method = " + method.Name)
	}
	for i := 0; i < fooType.NumField(); i++ {
		field := fooType.Field(i)
		fmt.Println("Field = " + field.Name)
		fmt.Println(reflect.ValueOf(value).Field(i))
	}
}
type TestType struct {
	TestString string
	TestNumber int
}
func (this *TestType) TestFunctionPtr() {
	fmt.Println("Test")
}
func (this TestType) TestFunction() {
	fmt.Println("Test Non Ptr")
}
Notice how the *Type can access also the Type Methods. But Type cannot access to *Type Methods.
To convert from Type to *Type I have used the reflect.PtrTo(Type).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论