Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use reflection to simplify Code in go language

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly analyzes the relevant knowledge points of how to use reflection to simplify the code in go language, the content is detailed and easy to understand, the operation details are reasonable, and has a certain reference value. If you are interested, you might as well follow the editor and learn more about how to use reflection to simplify code in the go language.

Reflection is a very important knowledge point in Go language. Reflection is the magic weapon of designing elegant programs, orm json serialization and parameter verification are inseparable from it. Today, we use an example in business development to briefly explain the use of reflection in daily development.

I believe that everyone will write such code when writing business code using go. The essence of this kind of code is to bind the data in a collection to the corresponding properties of the structure by name. The type of the collection is not limited to map slice struct or even interface [^ interface].

[^ interface]: this is compared to trick

Type TestValue struct {IntValue int StringValue string IntArray [] int StringArray [] string} dataMap: = map [string] string {"int_value": "1", "string_value": "str", "int_array": "[1J 2jue 3]", "string_array": "[\" 1\ ",\" 2\ ",\" 3\ "]" } config: = TestValue {} if value, ok: = dataMap ["int_value"] Ok {config.IntValue, _ = datautil.TransToInt64 (value)} if value, ok: = dataMap ["string_value"]; ok {config.StringValue = value} if value, ok: = dataMap ["int_array"]; ok {config.IntArray = stringToIntArray (value)} if value, ok: = dataMap ["string_array"]; ok {config.StringArray = stringToStrArray (value)} return config

The most frustrating thing in this part of the code is that when the structure is assigned, it is copied one by one. If the whole structure is very large, the assignment code may be full of screen, and the probability of bug occurrence will be greatly increased. Our goal is to simplify the assignment steps through reflection and bind the data in the collection to the structure in a way.

Brief description of reflection

To do this, let's first look at what our variables are made of in the go language.

_ type type information

* pointer to the actual value of data

Itab interface method

The first type on the figure is a reflection type object, which represents some information about the variable type, and the second represents the type corresponding to the structure attribute, which contains some information about the structure attribute.

Reflect.Type: / go/src/reflect/value.go:36

Bind function

When we see this picture, we probably know what to do. The goal is to write a binding method. We must establish a binding relationship, add a tag to this structure, and associate it with the data in tag and map.

/ / create a tag type TestValue struct {IntValue int `qiudianzan: "int_value" `StringValue string `qiudianzan: "string_value" `IntArray [] int `qiudianzan: "int_array" `StringArray [] string `qiudianzan: "string_array" `}

Then get the tag of the structure, which is easily done through reflection

Func bind (configMap map [string] string, result interface {}) error {v: = reflect.ValueOf (result). Elem () t: = v.Type () for I: = 0; I < t.NumField (); iTunes + {tag: = t.Field (I) .Tag.Get ("qiudianzan") fmt.Println (tag)}

After the binding relationship is completed, you need to write the value in map to the structure. at this time, the data structures in map are all string, but there are a variety of structure attribute types, so you can't write the data in map directly, and you need to do a step of type conversion according to the structure attribute type.

V.Field (I) .SetInt (res) v.Field (I) .SetUint (res) v.Field (I) .SetFloat (res). . .

Two types of reflection objects that represent attributes can be obtained through reflection

Reflect.Type / / static type reflect.Kind / / Type of underlying data

Let's use the following example to determine which one to use

Type A struct {} func main () {var an A kinda: = reflect.ValueOf (a) .Kind () typea: = reflect.TypeOf (a) fmt.Println (kinda) fmt.Println (typea)} struct main.A

The static type of variable an is A, but the underlying data type of an is struct, so we want to parse according to the type, which means reflect.Kind.

Convert data in map through underlying data types

Switch v.Field (I) .Kind () {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: res, err: = strconv.ParseInt (value, 10 64) if err! = nil {return err} v.Field (I) .SetInt (res) case reflect.String: v.Field (I) .SetString (value) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: res, err: = strconv.ParseUint (value, 10) 64) if err! = nil {return err} v.Field (I) .SetUint (res)

Add a little more detail, and a simple binding function is done.

Func bind (configMap map [string] string Result interface {}) error {/ / the bound structure returned if reflect.ValueOf (result) .Kind ()! = reflect.Ptr {return errors.New ("input not point")} / / the bound structure pointer returned if reflect.ValueOf (result) for the null error. IsNil () {return errors.New ("input is null")} v : = reflect.ValueOf (result) .Elem () t: = v.Type () for I: = 0 I < t.NumField () Value is skipped if there is no such variable in iSuppli + {tag: = t.Field (I) .Tag.Get ("json") / / map Ok: = configMap [tag] if! ok {continue} / / Skip the private variable if! v.Field (I). CanSet () {continue} switch v.Field (I). Kind () {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: res Err: = strconv.ParseInt (value, 10,64) if err! = nil {return err} v.Field (I) .SetInt (res) case reflect.String: v.Field (I) .SetString (value) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: res, err: = strconv.ParseUint (value, 10) 64) if err! = nil {return err} v.Field (I) .SetUint (res) case reflect.Float32: res, err: = strconv.ParseFloat (value) 32) if err! = nil {return err} v.Field (I) .SetFloat (res) case reflect.Float64: res, err: = strconv.ParseFloat (value) 64) if err! = nil {return err} v.Field (I) .SetFloat (res) case reflect.Slice: var strArray [] string var valArray [] reflect.Value var valArr reflect.Value elemKind: = t.Field (I) .Type.Elem (). Kind () ElemType: = t.Field (I) .Type.Elem () value = strings.Trim (strings.Trim (value "[") strArray = strings.Split (value, ",") switch elemKind {case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: for _, e: = range strArray {ee, err: = strconv.ParseInt (e, 10) 64) if err! = nil {return err} valArray = append (valArray, reflect.ValueOf (ee) .Convert (elemType))} case reflect.String: for _, e: = range strArray {valArray = append (valArray) Reflect.ValueOf (strings.Trim (e, "\")) .convert (elemType)}} valArr = reflect.Append (v.Field (I), valArray...) V.Field (I) .set (valArr)}} return nil}

The code that looked very ugly before became very simple in an instant.

Type TestValue struct {IntValue int StringValue string IntArray [] int StringArray [] string} dataMap: = map [string] string {"int_value": "1", "string_value": "str", "int_array": "[1J 2jue 3]", "string_array": "[\" 1\ ",\" 2\ ",\" 3\ "]" } config: = TestValue {} err: = bind (dataMap,&config)

Here only provides a binding idea, in fact, in the actual development, encounter structure value binding / verification / format / method binding, you can use similar ideas to avoid writing one by one code.

This is the end of the introduction on "how to use reflection to simplify code in the go language". More related content can be searched for previous articles, hoping to help you answer questions and questions, please support the website!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report