A Go package providing utility functions for reflection-based operations and type conversions.
This package provides utilities for:
- Converting generic interface{} / any values into specific types using reflection (inspired by Rust's TryInto / Into traits)
- Working with struct tags and reflection for field manipulation
- Type-safe reflection operations with compile-time safety
go get github.com/seyedali-dev/go-reflection-misc- Type conversion from interface{} to specific types with error handling
- Struct field manipulation using reflection
- Struct tag parsing and manipulation
- Type-safe reflection API
- Zero-value checking for various Go types
Converts a generic interface{} value to a specific type with error handling:
package main
import (
"fmt"
"log"
"github.com/seyedali-dev/go-reflection-misc"
)
func main() {
// Example 1: Conversion from compatible type
var x any = "123"
num, err := reflectx.TryInto[int](x)
if err != nil {
log.Fatal(err)
}
fmt.Println(num) // Output: 123 (if convertType handles string→int)
// Example 2: Nil input
var y any = nil
str, err := reflectx.TryInto[string](y)
if err != nil {
fmt.Println("Error:", err) // Output: Error: cannot convert type from nil interface
}
// Example 3: Direct type match
var z any = 42
result, err := reflectx.TryInto[int](z)
if err != nil {
log.Fatal(err)
}
fmt.Println(result) // Output: 42
}The result.Result version of TryInto:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
"github.com/seyedali-dev/goxide/rusty/result"
)
func main() {
var x any = "hello"
result := reflectx.TryIntoResult[string](x)
if result.IsOk() {
fmt.Println(result.Unwrap()) // Output: hello
} else {
fmt.Println("Error:", result.Err())
}
}The panic version of TryInto (panics on error):
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
func main() {
var x any = 42
result := reflectx.Into[int](x)
fmt.Println(result) // Output: 42
}The result.Result version of Into:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
func main() {
var x any = "hello"
result := reflectx.IntoResult[string](x)
if result.IsOk() {
fmt.Println(result.Unwrap()) // Output: hello
}
}Checks if a value is the zero value for its type:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
func main() {
fmt.Println(reflectx.IsEmpty("")) // true (empty string)
fmt.Println(reflectx.IsEmpty(0)) // true (zero int)
fmt.Println(reflectx.IsEmpty([]int{})) // true (empty slice)
fmt.Println(reflectx.IsEmpty("hello")) // false
fmt.Println(reflectx.IsEmpty(42)) // false
}Returns the value of a specific struct tag:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string `step:"profile" step_category:"employee"`
}
func main() {
value := reflectx.FieldTagValue(User{}, "Name", "step_category", "")
fmt.Println(value) // Output: employee
}Checks if a field has all specified tags:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string `step:"profile" step_category:"employee"`
}
func main() {
hasTags := reflectx.FieldHasTags(User{}, "Name", []string{"step", "step_category"})
fmt.Println(hasTags) // Output: true
}Returns all tag keys for a specific field:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string `step:"profile" step_category:"employee"`
}
func main() {
keys := reflectx.FieldTagKeys(User{}, "Name")
fmt.Println(keys) // Output: [step step_category]
}Returns the tag key and value for a specific field:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string `step:"profile" step_category:"employee"`
}
func main() {
key, value, found := reflectx.FieldTagKeyValue(User{}, "Name", "step", "")
if found {
fmt.Printf("Key: %s, Value: %s\n", key, value) // Output: Key: step, Value: profile
}
}Returns the field struct information:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string
Age int
}
func main() {
field := reflectx.Field(User{}, "Name")
fmt.Println(field.Name) // Output: Name
fmt.Println(field.Type) // Output: string
}Sets a field on the given object using reflection:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string
Age int
}
func main() {
user := &User{}
err := reflectx.FieldSet(user, "Name", "John Doe")
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println(user.Name) // Output: John Doe
}
}Returns the field value and whether it's settable:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
"reflect"
)
type User struct {
Name string
}
func main() {
user := &User{Name: "John"}
value, settable := reflectx.FieldValue(user, "Name")
if settable {
fmt.Println(value.String()) // Output: John
}
}Returns all fields of a struct:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string
Age int
}
func main() {
fields := reflectx.Fields(User{})
for _, field := range fields {
fmt.Println(field.Name, field.Type) // Output: Name string, Age int
}
}Returns the values of all fields in a struct:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string
Age int
}
func main() {
user := User{Name: "John", Age: 30}
values := reflectx.FieldValues(user)
for _, value := range values {
fmt.Println(value) // Output: John, 30
}
}Returns the name of the first field where a tag has a specific value:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Field1 string `step_category:"employee"`
Field2 string `step_category:"customer"`
}
func main() {
fieldName := reflectx.FieldNameByTagValue(User{}, "step_category", "employee")
fmt.Println(fieldName) // Output: Field1
}Returns the names of all fields where a tag has a specific value:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Field1 string `step_category:"employee"`
Field2 string `step_category:"customer"`
Field3 string `step_category:"employee"`
}
func main() {
fieldNames := reflectx.FieldNamesByTagValue(User{}, "step_category", "employee")
fmt.Println(fieldNames) // Output: [Field1 Field3]
}Returns all values for a specific struct tag key:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string `step_restrictions:"emp_only,has_code"`
}
func main() {
values := reflectx.FieldTagValues(User{}, "Name", "step_restrictions", ",")
fmt.Println(values) // Output: [emp_only has_code]
}Checks if a field has a specific value in a multi-value tag:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string `step_restrictions:"emp_only,has_code"`
}
func main() {
hasValue := reflectx.FieldHasTagValue(User{}, "Name", "step_restrictions", "has_code", ",")
fmt.Println(hasValue) // Output: true
}Returns all fields where a tag contains a specific value:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Field1 string `step_restrictions:"emp_only,has_code"`
Field2 string `step_restrictions:"customer"`
Field3 string `step_restrictions:"has_code"`
}
func main() {
fields := reflectx.FieldsByTagContainsValue(User{}, "step_restrictions", "has_code", ",")
for _, field := range fields {
fmt.Println(field.Name) // Output: Field1 Field3
}
}Returns the fully-qualified name of the struct type:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct{}
func main() {
name := reflectx.StructTypeName(User{})
fmt.Println(name) // Output: main.User (or the package path)
}For compile-time safety, you can create a reflector for a specific type:
package main
import (
"fmt"
"github.com/seyedali-dev/go-reflection-misc"
)
type User struct {
Name string `step:"profile" step_category:"employee"`
}
func main() {
// Create type-safe reflector once
userReflector := reflectx.ForType[User]()
// Now get compile-time safety
tagValue := userReflector.FieldTagValue("Name", "step_category", "")
hasTags := userReflector.FieldHasTags("Name", []string{"step", "step_category"})
fmt.Println(tagValue) // Output: employee
fmt.Println(hasTags) // Output: true
// This would cause IDE/compiler errors if fields don't exist:
// userReflector.FieldTagValue("NonExistentField", "tag") // Compile error
}TryInto[T any](structType any) (T, error): Attempts to convert a generic value to type T with error handlingTryIntoResult[T any](structType any) result.Result[T]: Result version of TryIntoInto[T any](structType any) T: Panic version of TryIntoIntoResult[T any](structType any) result.Result[T]: Result version of IntoIsEmpty[T any](v T) bool: Checks if a value is the zero value for its type
FieldTagValue(structType interface{}, fieldName string, tag string, tagValSeparator string) string: Returns the value of a specific struct tagFieldHasTags(structType interface{}, fieldName string, tags []string) bool: Checks if a field has all specified tagsFieldTagKeys(structType interface{}, fieldName string) []string: Returns all tag keys for a fieldFieldTagKeyValue(structType interface{}, fieldName string, tagKey string, tagValSeparator string) (key string, value string, found bool): Returns the tag key and value for a fieldField(structType interface{}, fieldName string) reflect.StructField: Returns field struct informationFieldSet(structType interface{}, fieldName string, value interface{}) error: Sets a field on an objectFieldValue(intrfc interface{}, fieldName string) (reflect.Value, bool): Returns field value and settable statusFields(structType interface{}) []reflect.StructField: Returns all fields of a structFieldValues(structInstance interface{}) []reflect.Value: Returns values of all fields in a structFieldNameByTagValue(structType interface{}, tagKey, expectedValue string) string: Returns the name of the first field with a specific tag valueFieldNamesByTagValue(structType interface{}, tagKey, expectedValue string) []string: Returns names of all fields with a specific tag valueFieldTagValues(structType interface{}, fieldName string, tagKey string, tagValSeparator string) []string: Returns all values for a specific tag keyFieldHasTagValue(structType interface{}, fieldName string, tagKey string, expectedValue string, tagValSeparator string) bool: Checks if a field has a specific value in a multi-value tagFieldsByTagContainsValue(structType interface{}, tagKey, expectedValue, tagValSeparator string) []reflect.StructField: Returns fields where a tag contains a specific valueStructTypeName(structType interface{}) string: Returns the fully-qualified name of a struct type
The Reflector[T] type provides type-safe versions of all struct reflection utilities with compile-time checking:
ForType[T any]() *Reflector[T]: Creates a type-safe reflectorFieldTagValue(fieldName string, tag string, tagValSeparator string) stringFieldHasTags(fieldName string, tags []string) boolFieldTagKeys(fieldName string) []stringFieldTagKeyValue(fieldName string, tagKey string, tagValSeparator string) (key string, value string, found bool)Field(fieldName string) reflect.StructFieldFieldValue(instance *T, fieldName string) (reflect.Value, bool)Fields() []reflect.StructFieldFieldValues(instance *T) []reflect.ValueFieldNameByTagValue(tagKey, expectedValue string) stringFieldNamesByTagValue(tagKey, expectedValue string) []stringFieldTagValues(fieldName string, tagKey string, tagValSeparator string) []stringFieldHasTagValue(fieldName string, tagKey string, expectedValue string, tagValSeparator string) boolFieldsByTagContainsValue(tagKey, expectedValue, tagValSeparator string) []reflect.StructFieldStructTypeName() string
This package includes benchmark tests for performance evaluation:
- Interface conversion benchmarks in
interface_benchmark_test.go - Struct reflection benchmarks in
reflection_struct_benchmark_test.go
Run benchmarks with:
go test -bench=.Run all tests with:
go test ./...The package includes:
- Unit tests for interface utilities in
interface_unit_test.go - Unit tests for struct reflection utilities in
reflect_struct_unit_test.go - End-to-end tests for struct reflection utilities in
reflection_struct_e2e_test.go
This project is licensed under the MIT License - see the LICENSE file for details.