反射类型没有该方法。

huangapple go评论82阅读模式
英文:

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 (
&quot;fmt&quot;
&quot;reflect&quot;
)

func main() {
    var B TestType = TestType{TestString: &quot;Hello&quot;, TestNumber: 3}
    ListMethods(B)
}

func ListMethods(value interface{}) {

    fooType := reflect.TypeOf(value)

	for i := 0; i &lt; fooType.NumMethod(); i++ {
    	method := fooType.Method(i)
	    fmt.Println(&quot;Method = &quot; + method.Name)
	}

    for i := 0; i &lt; fooType.NumField(); i++ {
	    field := fooType.Field(i)
	    fmt.Println(&quot;Field = &quot; + field.Name)
	    fmt.Println(reflect.ValueOf(value).Field(i))
    }
}

type TestType struct {
    TestString string
    TestNumber int
}

func (this *TestType) TestFunction() {
    fmt.Println(&quot;Test&quot;)
}

答案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 (
	&quot;fmt&quot;
	&quot;reflect&quot;
)

func main() {
	var B TestType = TestType{TestString: &quot;Hello&quot;, TestNumber: 3}
	ListMethods(B)
}

func ListMethods(value interface{}) {

	fooType := reflect.TypeOf(value)
	ptrFooType := reflect.PtrTo(fooType)

	for i := 0; i &lt; fooType.NumMethod(); i++ {
		method := fooType.Method(i)
		fmt.Println(&quot;Method = &quot; + method.Name)
	}

	for i := 0; i &lt; ptrFooType.NumMethod(); i++ {
		method := ptrFooType.Method(i)
		fmt.Println(&quot;* Method = &quot; + method.Name)
	}

	for i := 0; i &lt; fooType.NumField(); i++ {
		field := fooType.Field(i)
		fmt.Println(&quot;Field = &quot; + field.Name)
		fmt.Println(reflect.ValueOf(value).Field(i))
	}
}

type TestType struct {
	TestString string
	TestNumber int
}

func (this *TestType) TestFunctionPtr() {
	fmt.Println(&quot;Test&quot;)
}

func (this TestType) TestFunction() {
	fmt.Println(&quot;Test Non Ptr&quot;)
}

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).

huangapple
  • 本文由 发表于 2014年8月29日 16:24:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/25564403.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定