Golang GoStdLib GoReflect
2021-02-17
func Copy(dst, src Value) int
func DeepEqual(x, y any) bool
func Swapper(slice any) func(i, j int)
type ChanDir
func (d ChanDir) String() string
type Kind
func (k Kind) String() string
type MapIter
func (iter *MapIter) Key() Value
func (iter *MapIter) Next() bool
func (iter *MapIter) Reset(v Value)
func (iter *MapIter) Value() Value
type Method
func (m Method) IsExported() bool
type SelectCase
type SelectDir
type SliceHeader
type StringHeader
type StructField
func VisibleFields(t Type) []StructField
func (f StructField) IsExported() bool
type StructTag
func (tag StructTag) Get(key string) string
func (tag StructTag) Lookup(key string) (value string, ok bool)
Type
func ArrayOf(length int, elem Type) Type
func ChanOf(dir ChanDir, t Type) Type
func FuncOf(in, out []Type, variadic bool) Type
func MapOf(key, elem Type) Type
func PointerTo(t Type) Type
func PtrTo(t Type) Type
func SliceOf(t Type) Type
func StructOf(fields []StructField) Type
func TypeOf(i any) Type
Value
func Append(s Value, x ...Value) Value
func AppendSlice(s, t Value) Value
func Indirect(v Value) Value
func MakeChan(typ Type, buffer int) Value
func MakeFunc(typ Type, fn func(args []Value) (results []Value)) Value
func MakeMap(typ Type) Value
func MakeMapWithSize(typ Type, n int) Value
func MakeSlice(typ Type, len, cap int) Value
func New(typ Type) Value
func NewAt(typ Type, p unsafe.Pointer) Value
func Select(cases []SelectCase) (chosen int, recv Value, recvOK bool)
func ValueOf(i any) Value
func Zero(typ Type) Value
func (v Value) Addr() Value
func (v Value) Bool() bool
func (v Value) Bytes() []byte
func (v Value) Call(in []Value) []Value
func (v Value) CallSlice(in []Value) []Value
func (v Value) CanAddr() bool
func (v Value) CanComplex() bool
func (v Value) CanConvert(t Type) bool
func (v Value) CanFloat() bool
func (v Value) CanInt() bool
func (v Value) CanInterface() bool
func (v Value) CanSet() bool
func (v Value) CanUint() bool
func (v Value) Cap() int
func (v Value) Close()
func (v Value) Comparable() bool
func (v Value) Complex() complex128
func (v Value) Convert(t Type) Value
func (v Value) Elem() Value
func (v Value) Equal(u Value) bool
func (v Value) Field(i int) Value
func (v Value) FieldByIndex(index []int) Value
func (v Value) FieldByIndexErr(index []int) (Value, error)
func (v Value) FieldByName(name string) Value
func (v Value) FieldByNameFunc(match func(string) bool) Value
func (v Value) Float() float64
func (v Value) Grow(n int)
func (v Value) Index(i int) Value
func (v Value) Int() int64
func (v Value) Interface() (i any)
func (v Value) InterfaceData() [2]uintptrDEPRECATED
func (v Value) IsNil() bool
func (v Value) IsValid() bool
func (v Value) IsZero() bool
func (v Value) Kind() Kind
func (v Value) Len() int
func (v Value) MapIndex(key Value) Value
func (v Value) MapKeys() []Value
func (v Value) MapRange() *MapIter
func (v Value) Method(i int) Value
func (v Value) MethodByName(name string) Value
func (v Value) NumField() int
func (v Value) NumMethod() int
func (v Value) OverflowComplex(x complex128) bool
func (v Value) OverflowFloat(x float64) bool
func (v Value) OverflowInt(x int64) bool
func (v Value) OverflowUint(x uint64) bool
func (v Value) Pointer() uintptr
func (v Value) Recv() (x Value, ok bool)
func (v Value) Send(x Value)
func (v Value) Set(x Value)
func (v Value) SetBool(x bool)
func (v Value) SetBytes(x []byte)
func (v Value) SetCap(n int)
func (v Value) SetComplex(x complex128)
func (v Value) SetFloat(x float64)
func (v Value) SetInt(x int64)
func (v Value) SetIterKey(iter *MapIter)
func (v Value) SetIterValue(iter *MapIter)
func (v Value) SetLen(n int)
func (v Value) SetMapIndex(key, elem Value)
func (v Value) SetPointer(x unsafe.Pointer)
func (v Value) SetString(x string)
func (v Value) SetUint(x uint64)
func (v Value) SetZero()
func (v Value) Slice(i, j int) Value
func (v Value) Slice3(i, j, k int) Value
func (v Value) String() string
func (v Value) TryRecv() (x Value, ok bool)
func (v Value) TrySend(x Value) bool
func (v Value) Type() Type
func (v Value) Uint() uint64
func (v Value) UnsafeAddr() uintptr
func (v Value) UnsafePointer() unsafe.Pointer
Golang GoReflect
2021-02-09
通过反射(Reflection),我们可以在程序运行时,动态的增删该一些信息(类型,方法,变量),用来完成一些特殊的任务。
主要是实现不同类型都支持的一些方法。在 ORM,序列化等方面都有应用。
这种动态获取信息的能力让程序的开发变得更加灵活,但也会损失部分性能,毕竟需要进行很多类型检查、值转换等操作。
而且,滥用的话会导致程序变得复杂,可读性下降。
示例 1
type Person struct {
Name string
Age int
}
func Insert(db *sql.DB, v interface{}) error {
value := reflect.ValueOf(v)
typ := reflect.TypeOf(v)
sql := "INSERT INTO persons ("
placeholders := "VALUES ("
for i := 0; i < typ.Elem().NumField(); i++ {
fieldName := typ.Elem().Field(i).Name
sql += fmt.Sprintf("%s, ", fieldName)
placeholders += "?, "
}
sql = sql[:len(sql)-2] + ")"
placeholders = placeholders[:len(placeholders)-2] + ")"
args := make([]interface{}, typ.Elem().NumField())
for i := 0; i < typ.Elem().NumField(); i++ {
args[i] = value.Elem().Field(i).Interface()
}
_, err := db.Exec(sql+placeholders, args...)
return err
}
示例 2
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
Address string
}
// 定义结构体方法
func (p Person) Hello() string {
return "Hello, " + p.Name
}
func main() {
p := Person{
Name: "Alice",
Age: 30,
Address: "123 Main St",
}
fmt.Println("获取变量的反射类型:===============")
pType := reflect.TypeOf(p) // &reflect.rtype
fmt.Printf("Type: %s, %#v\n", pType, pType) // main.Person
// fmt.Println("Type:", pType.Elem()) // panic: reflect: Elem of invalid type main.Person
pType2 := reflect.TypeOf(&p)
fmt.Printf("Type: %s, %#v\n", pType2, pType2) // *main.Person
fmt.Printf("Type: %s, %#v\n", pType2.Elem(), pType2.Elem()) // main.Person (指针类型的基础类型)
fmt.Println("获取变量的反射值:===============")
pValue := reflect.ValueOf(p) // main.Person
fmt.Printf("Value: %s, %#v\n", pValue, pValue)
pValue2 := reflect.ValueOf(&p)
fmt.Printf("Value: %s, %#v\n", pValue2, pValue2) // 地址
fmt.Printf("Value: %s, %#v\n", pValue2.Elem(), pValue2.Elem())
fmt.Println("遍历结构体字段:===============")
for i := 0; i < pType.NumField(); i++ {
field := pType.Field(i)
value := pValue.Field(i)
fmt.Printf("%s: %v\n", field.Name, value.Interface())
}
fmt.Println("修改结构体字段值:===============")
ageField1 := pValue.FieldByName("Age")
fmt.Printf("Value: %#v\n", ageField1)
// ageField1.SetInt(31) // panic: reflect: reflect.Value.SetInt using unaddressable value
// ageField1.Elem().SetInt(31) // panic: reflect: call of reflect.Value.Elem on int Value
ageField2 := pValue2.Elem().FieldByName("Age")
fmt.Printf("Value: %#v\n", ageField2)
ageField2.SetInt(31) // 只有指针类型才能通过反射修改
fmt.Println("New Age:", p.Age)
fmt.Println("调用结构体方法:===============")
helloMethod := pValue.MethodByName("Hello")
result := helloMethod.Call(nil)
fmt.Println(result)
// panic: reflect: call of reflect.Value.FieldByName on ptr Value
pValue2.FieldByName("Age")
// panic: reflect: reflect.Value.SetInt using unaddressable value
// a := reflect.Indirect(pValue)
b := reflect.Indirect(pValue2)
b.FieldByName("Age").SetInt(33)
fmt.Printf("%#v\n", b)
}
reflect.TypeOf
:获取变量的类型
-
reflect.ValueOf
:获取变量的值
Type.NumField
:获取结构体字段数量
-
Type.Field
:获取结构体字段信息
-
Value.Field
:获取结构体字段的值
Value.FieldByName
:根据字段名获取结构体字段的值
Value.SetInt
:设置整数类型字段的值
Value.MethodByName
:根据方法名获取结构体方法
Value.Call
:调用结构体方法