Use reflect.ValueOf and reflect.TypeOf to get runtime values and types; 2. Inspect type details with reflect.Type methods like Name() and Kind(); 3. Modify values via reflect.Value.Elem() and CanSet() after passing a pointer; 4. Call methods dynamically using MethodByName() and Call(); 5. Read struct tags via Field(i).Tag.Get("key") for metadata-driven logic; use reflection for generic libraries, config parsing, and dynamic access but prefer generics over reflection when possible for better performance and safety.
Reflection in Go allows you to examine and manipulate variables, types, and values at runtime. It's powerful but should be used carefully, as it can make code harder to read and debug. The main package for reflection is reflect
.

Here’s how to use reflection in Go, broken down into practical parts.
1. Understanding reflect.Value
and reflect.Type
At the core of Go’s reflection are two main types:

-
reflect.Value
— represents the value of an interface. -
reflect.Type
— represents the type of a value.
You get them using:
v := reflect.ValueOf(x) t := reflect.TypeOf(x)
Example:

package main import ( "fmt" "reflect" ) func main() { var name = "Alice" fmt.Println("Type:", reflect.TypeOf(name)) // string fmt.Println("Value:", reflect.ValueOf(name)) // Alice }
Note:
reflect.ValueOf
returns a copy of the data, not a reference.
2. Getting Type Information
Use reflect.TypeOf
to inspect the type of a variable.
var age int = 42 t := reflect.TypeOf(age) fmt.Println(t.Name()) // int fmt.Println(t.Kind()) // int
For structs:
type Person struct { Name string Age int } p := Person{Name: "Bob", Age: 30} t = reflect.TypeOf(p) fmt.Println(t.Name()) // Person fmt.Println(t.Kind()) // struct // Loop through fields for i := 0; i < t.NumField(); i { field := t.Field(i) fmt.Printf("Field: %s, Type: %s\n", field.Name, field.Type) }
Output:
Field: Name, Type: string Field: Age, Type: int
3. Modifying Values with Reflection
To modify a value, you need a pointer to it, because reflection works on copies otherwise.
Use reflect.Value.Elem()
to get the value a pointer points to.
func setToZero(x interface{}) { v := reflect.ValueOf(x) if v.Kind() != reflect.Ptr { panic("Expected a pointer") } // Get the value that the pointer points to v = v.Elem() if v.CanSet() { switch v.Kind() { case reflect.String: v.SetString("") case reflect.Int: v.SetInt(0) } } } func main() { name := "Hello" age := 25 setToZero(&name) setToZero(&age) fmt.Println(name) // "" fmt.Println(age) // 0 }
CanSet()
checks if the value is addressable (i.e., you can modify it).
4. Calling Methods Dynamically
You can use reflection to call methods by name.
type Greeter struct{} func (g Greeter) SayHello(name string) { fmt.Println("Hello,", name) } func main() { g := Greeter{} v := reflect.ValueOf(g) // Get method by name method := v.MethodByName("SayHello") if method.IsValid() { args := []reflect.Value{reflect.ValueOf("Alice")} method.Call(args) } }
Output:
Hello, Alice
Note: Only exported (capitalized) methods can be accessed.
5. Working with Struct Tags
Reflection is often used to read struct tags (like in JSON marshaling).
type User struct { Name string `json:"name" validate:"required"` Age int `json:"age"` } func printJSONTags(u interface{}) { t := reflect.TypeOf(u) for i := 0; i < t.NumField(); i { field := t.Field(i) jsonTag := field.Tag.Get("json") validateTag := field.Tag.Get("validate") fmt.Printf("Field: %s, json tag: %s, validate: %s\n", field.Name, jsonTag, validateTag) } } func main() { var u User printJSONTags(u) }
Output:
Field: Name, json tag: name, validate: required Field: Age, json tag: age, validate:
This is how packages like encoding/json
know how to marshal fields.
When to Use Reflection
Reflection is useful for:
- Building generic libraries (e.g., ORMs, serializers)
- Configuration parsing (YAML/JSON to structs)
- Dynamic method or field access
- Validation frameworks
But avoid it when:
- Performance is critical (reflection is slow)
- You can use interfaces or generics (Go 1.18 )
- Simpler alternatives exist
Bonus: Generics vs Reflection
Since Go 1.18, generics can often replace reflection for type-safe generic code.
For example, instead of using reflection to zero a value, you could write:
func SetZero[T any](x *T) { *x = *new(T) }
This is faster and safer than reflection.
So: Use generics when possible, reflection when necessary.
Basically, reflection gives you deep introspection power in Go — just don’t overuse it. Know Type
, Value
, Kind
, and how to set values safely, and you’re good to go.
The above is the detailed content of How to use reflection in Go?. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

Go's switch statement will not be executed throughout the process by default and will automatically exit after matching the first condition. 1. Switch starts with a keyword and can carry one or no value; 2. Case matches from top to bottom in order, only the first match is run; 3. Multiple conditions can be listed by commas to match the same case; 4. There is no need to manually add break, but can be forced through; 5.default is used for unmatched cases, usually placed at the end.

Usereflect.ValueOfandreflect.TypeOftogetruntimevaluesandtypes;2.Inspecttypedetailswithreflect.TypemethodslikeName()andKind();3.Modifyvaluesviareflect.Value.Elem()andCanSet()afterpassingapointer;4.CallmethodsdynamicallyusingMethodByName()andCall();5.R

In Go, to break out of nested loops, you should use labeled break statements or return through functions; 1. Use labeled break: Place the tag before the outer loop, such as OuterLoop:for{...}, use breakOuterLoop in the inner loop to directly exit the outer loop; 2. Put the nested loop into the function, and return in advance when the conditions are met, thereby terminating all loops; 3. Avoid using flag variables or goto, the former is lengthy and easy to make mistakes, and the latter is not recommended; the correct way is that the tag must be before the loop rather than after it, which is the idiomatic way to break out of multi-layer loops in Go.

Usecontext.WithTimeouttocreateacancellablecontextwithadeadlineandalwayscallcancel()toreleaseresources.2.ForHTTPrequests,settimeoutsusinghttp.Client.Timeoutorusecontextviahttp.NewRequestWithContextforper-requestcontrol.3.Ingoroutineswithchannels,usese

Usecontexttopropagatecancellationanddeadlinesacrossgoroutines,enablingcooperativecancellationinHTTPservers,backgroundtasks,andchainedcalls.2.Withcontext.WithCancel(),createacancellablecontextandcallcancel()tosignaltermination,alwaysdeferringcancel()t

UsestructswithPERJSontagsFeRpredictabledatoensurefast, safeparsingwithcompile-timetypesafety.2.avoidmap [string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] interface {string] }duetoreflectionoverheadandruntimetypeassertionsunlessdealingwithtrulydynamicJSON.3.Usejson.RawMessagefordeferredorselectivep

InitializeaGomodulewithgomodinit,2.InstallgqlgenCLI,3.Defineaschemainschema.graphqls,4.Rungqlgeninittogeneratemodelsandresolvers,5.Implementresolverfunctionsforqueriesandmutations,6.SetupanHTTPserverusingthegeneratedschema,and7.RuntheservertoaccessGr

Gooffersfasterexecutionspeedduetocompilationtonativemachinecode,outperforminginterpretedlanguageslikePythonintaskssuchasservingHTTPrequests.2.Itsefficientconcurrencymodelusinglightweightgoroutinesenablesthousandsofconcurrentoperationswithlowmemoryand
