SoFunction
Updated on 2025-03-03

Example of Go language reflection to obtain type attributes and methods

and

If the variable is a structure, we can also obtain the type attributes of the fields under the structure through the structure domain type object. The Type interface provides many methods for obtaining field structure domain type objects. We mainly introduce the following interfaces:

	// Get the number of fields in a structure	NumField() int
	// Get the member field type object in the structure according to index	Field(i int) StructField
	// Get the member field type object in the structure according to the field name	FieldByName(name string) (StructField, bool)

Through the above 3 methods, we can easily get the type object of all member fields in a structure variable. Through , we can know the type and type to which the member field belongs, which are mainly composed of the following properties:

type StructField struct {
	// Name of member field	Name string
	// Member field Type	Type      Type
	// Tag
	Tag       StructTag
	// Byte offset	Offset    uintptr
	// index of member fields	Index     []int
	// Is the member field public?	Anonymous bool
}

StructField

StructField provides Type information for obtaining field type information, while StructTag is generally used to describe additional information for struct member fields, such as it will be used when JSON is serialized and object mapping. StructTag is generally composed of one or more key-value pairs. A simple example is as follows:

ID string `json:"id"`

Keys and values ​​are separated by :, values ​​are enclosed with "", and key-value pairs are separated by spaces. The example above shows that the ID field will be changed to id when serialized by JSON.

Traversal of Hero structure

Next, we traverse the Hero structure, get the type of the field inside it and output it, the code is as follows:

func main()  {
	typeOfHero := (Hero{})
	// by #NumField Gets the number of structure fields for i := 0 ; i < (); i++{		("field' name is %s, type is %s, kind is %s\n", (i).Name, (i).Type, (i).())
	}
	// Get the member field type object with name Name	nameField, _ := ("Name")
	("field' name is %s, type is %s, kind is %s\n", , , ())
}

The expected results are as follows:

field' name is Name, type is string, kind is string
field' name is Age, type is int, kind is int
field' name is Speed, type is int, kind is int
field' name is Name, type is string, kind is string

In the above code, first use Type#NumField to obtain the number of fields in the Hero structure, and then use typeOfHero#Field to obtain each field domain type object according to the index and print their type information. The code ends up demonstrating how to get a field domain type object with the field name Name through typeOfHero#FieldByName.

Method

In addition to obtaining the field domain type object under the structure, Type also provides a method to obtain the method type object Method of the method under the interface. The interface method description is as follows:

	// Find the method according to index	Method(int) Method
	// Find the method according to the method name	MethodByName(string) (Method, bool)
	// Get the number of methods disclosed in the type	NumMethod() int

The obtained method type description object Method describes the basic information of the method, including method name, method type, etc. The code is as follows:

type Method struct {
	// Method name	Name    string
	// Method type	Type  Type
	// Reflection object, can be used to call methods	Func  Value
	// index of method	Index int
}

In Method, the Func field is a reflective value object that can be used to make method calls. If Method is a Type obtained from interface type reflection, then the first parameter passed by Func needs to be the receiver that implements the method. We will introduce this part of the difference in Value.

We can obtain the method type object of the method in the interface Person through the methods provided in Type. The code is as follows:

func main()  {
	// Declare a Person interface and use Hero as the receiver		var person Person = &Hero{}
	// Get the type object of interface Person	typeOfPerson := (person)
	// Print Person's method type and name	for i := 0 ; i < (); i++{
		("method is %s, type is %s, kind is %s.\n", (i).Name, (i).Type, (i).())
	}
	method, _ := ("Run")
	("method is %s, type is %s, kind is %s.\n", , , ())
	}

The expected output is as follows:

method is Run, type is func(*), kind is func
method is SayHello, type is func(*, string), kind is func
method is Run, type is func(*) string, kind is func.

In addition to obtaining method type objects according to index through typeOfPerson#Method, you can also use typeOfPerson#MethodByName to find the corresponding method type objects according to the method name. From the output results, we can see that the types of methods are func, and the types are declarations of methods.

summary

This article mainly introduces the reflection basis and . Through reflection, we can get type information and definition methods, etc. Go's reflection realizes most of the functions of reflection. To obtain type information, you need to use the lexical method, grammar parser and abstract grammatical numbers in the standard library to scan the source code. The next article will continue to introduce the reflection value object related to Go language.

The above is the detailed content of Go language reflection obtaining type attributes and methods. For more information about Go reflection obtaining type attribute methods, please pay attention to my other related articles!