golang反射

メソッド関数呼び出しオブジェクト実行時のプロパティを動的にオブジェクトを取得するための反射手段。golangサポート反射、ネイティブのJSONライブラリは、達成するためにリフレクションを使用することです。

:2つの主反射golangの概念があるreflect.Typereflect.Value理解種類と、文字通りの値は、

reflect.Type

reflect.Typeそれはによって、種類、基本的なint型、文字列を指し、または構造のカスタム型であってもよいreflect.TypeOf()買収ターゲットのタイプ

TypeOf(i interface{}) Type  // 获取任意一个对象的 Type 对象

(t *Type) NumField() int    // 字段数量
(t *Type) NumMethod() int   // 方法数量
(t *Type) Field(i int) StructField  // 返回第 i 个字段
(t *Type) FieldByName(name string) (StructField, bool)  // 根据字段名获取字段
(t *Type) Name()            // 字段名
(t *Type) Kind() Kind       // 字段类型

type StructField struct {
	Name    string      // 字段名
	PkgPath string      // 包路径
	Type    Type        // 字段类型
    Tag     StructTag   // 字段的 tag
}

(tag StructTag) Get(key string) string  // 获取字段的 tag 中的某个 key

reflect.Value

reflect.Value 値を参照し、メインのAPI

ValueOf(i interface{}) Type  // 获取任意一个对象的 Value 对象

(v Value) NumField() int    // 字段数量
(v Value) NumMethod() int   // 方法数量
(v Value) Field(i int) Value        // 返回第 i 个字段
(v Value) Method(int) Value         // 返回第 i 个方法
(v Value) FieldByName(name string) Value    // 根据字段名获取字段
(v Value) MethodByName(string) Value        // 根据方法名获取字段
(v Value) Type() Type       // 获取的类型

(v Value) Int() int         // 返回 int
(v Value) String() string   // 返回 string
(v Value) Interface() interface{}   // 返回一个 interface,之后可以转成任意对象

(v Value) Call(in []Value) []Value      // 方法调用,参数和返回值都是数组的形式
(v Value) CallSlice(in []Value) []Value // 可变长参数函数调用

例えば

type A struct {
	F1 int    `json:"f1"`
	F2 string `json:"f2"`
}

タイプを取得します。

t := reflect.TypeOf(A{})
So(t.NumField(), ShouldEqual, 2)
So(t.Field(0).Name, ShouldEqual, "F1")
So(t.Field(0).Type.Kind(), ShouldEqual, reflect.Int)
So(t.Field(0).Tag, ShouldEqual, `json:"f1"`)
So(t.Field(1).Name, ShouldEqual, "F2")
So(t.Field(1).Type.Kind(), ShouldEqual, reflect.String)
So(t.Field(1).Tag, ShouldEqual, `json:"f2"`)

タグ

So(reflect.TypeOf(A{}).Field(0).Tag.Get("json"), ShouldEqual, "f1")
So(reflect.TypeOf(A{}).Field(1).Tag.Get("json"), ShouldEqual, "f2")

値を取得します。

a := A{
    F1: 10,
    F2: "hatlonely",
}
v := reflect.ValueOf(a)
So(v.NumField(), ShouldEqual, 2)
So(v.Field(0).Int(), ShouldEqual, 10)
So(v.Field(1).String(), ShouldEqual, "hatlonely")
So(v.Field(0).Type().Kind(), ShouldEqual, reflect.Int)
So(v.Field(1).Type().Kind(), ShouldEqual, reflect.String)
So(v.FieldByName("F1").Int(), ShouldEqual, 10)
So(v.FieldByName("F2").Interface().(string), ShouldEqual, "hatlonely")

ここで注意すべき方法は、その呼び出し方法、receiverポインタであるか、または受信機の目的、価値及びタイプは一貫しているべき

func (a *A) Add(b int) int {
	a.F1 += b
	return a.F1
}

func (a A) Mul(b int) int {
	return a.F1 * b
}

func (a A) Sum(vi ...int) int {
	sum := 0
	for _, i := range vi {
		sum += i
	}

	return sum + a.F1
}

a := A{
    F1: 10,
}

So(reflect.ValueOf(a).MethodByName("Mul").Call([]reflect.Value{reflect.ValueOf(20)})[0].Int(), ShouldEqual, 200)
So(a.F1, ShouldEqual, 10)
So(reflect.ValueOf(&a).MethodByName("Add").Call([]reflect.Value{reflect.ValueOf(20)})[0].Int(), ShouldEqual, 30)
So(a.F1, ShouldEqual, 30)
So(reflect.ValueOf(a).MethodByName("Sum").Call([]reflect.Value{
    reflect.ValueOf(30), reflect.ValueOf(40), reflect.ValueOf(50),
})[0].Int(), ShouldEqual, 150)
So(reflect.ValueOf(a).MethodByName("Sum").CallSlice([]reflect.Value{
    reflect.ValueOf([]int{30, 40, 50}),
})[0].Int(), ShouldEqual, 150)

リンク

:元記事のリンクを明記してくださいhttps://tech.hatlonely.com/article/59を

おすすめ

転載: www.cnblogs.com/hatlonely/p/11945431.html