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

Example Analysis of Interface reflection of structural struct Interface in Go language

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article shows you the Go language structure struct interface Interface reflection example analysis, the content is concise and easy to understand, can definitely brighten your eyes, through the detailed introduction of this article, I hope you can get something.

Structural struct

Struct is used to customize complex data structures. It can contain multiple fields (properties) and can be nested.

The struct type in go is understood as a class, and you can define methods, which are slightly different from function definitions.

The struct type is a value type.

Struct definition

Type User struct {Name string Age int32 mess string} var user Uservar user1 * User = & User {} var user2 * User = new (User)

Struct usage

In the following example, user1 and user2 are pointer types, and the compiler automatically converts user1.Name to (* user1). Name when accessed.

Func main () {var user User user.Name = "nick" user.Age = 18 user.mess = "lover" var user1 * User = & User {Name: "dawn", Age: 21,} fmt.Println (* user1) / / {dawn 21} fmt.Println (user1.Name (* user1) .Name) / / dawn dawn var user2 * User = new (User) user2.Name = "suoning" user2.Age = 18 fmt.Println (user2) / / & {suoning 18} fmt.Println (user2.Name, (* user2) .Name) / / suoning suoning}

Constructor function

Struct in golang has no constructor and can forge a

Type User struct {Name string Age int32 mess string} func NewUser (name string, age int32, mess string) * User {return & User {Name:name,Age:age,mess:mess}} func main () {/ / user: = new (User) user: = NewUser ("suoning", 18, "lover") fmt.Println (user, user.mess, user.Name, user.Age)}

Memory layout

All fields in struct are continuous in memory

Var user User user.Name = "nick" user.Age = 18 user.mess = "lover" fmt.Println (user) / / {nick 18 lover} fmt.Printf ("Name:%p\ n", & user.Name) / / Name:0xc420016180 fmt.Printf ("Age:% p\ n", & user.Age) / / Age: 0xc420016190 fmt.Printf ("mess:%p\ n", & user.mess) / / mess:0xc420016198 8 bytes are memory aligned

Method

Methods act on specific types of variables, so custom types can have methods, not just struct.

The access control of the method is also controlled by case.

The init function is implemented by passing in a pointer, which changes the value of the struct field because it is a value type.

Type User struct {Name string Age int sex string} func (this * User) init (name string, age int, sex string) {this.Name = name this.Age = age this.sex = sex} func (this User) GetName () string {return this.Name} func main () {var user User user.init ("nick", 18, "man") / / (& user) .init ("nick", 18, "man") name: = user.GetName () fmt.Println (name)}

Anonymous field

If there is a conflict, the outermost priority

Type User struct {Name stirng Age int} type Lover struct {User sex time.Time int Age int}

Inheritance & multiple inheritance

A structure inherits multiple structures and accesses pass-through points. Inherit fields and methods.

You can use an alias, such as U1 (user1) below, to access user.u1.Age.

If all inherited structures have the same field, an error will be reported when accessed through user.name and must be accessed through user.user1.name.

Type user1 struct {name string Age int} type user2 struct {name string age int sex time.Time} type User struct {U1 user1 / / alias user2 Name string Age int} func main () {var user User user.Name = "nick" user.u1.Age = 18 fmt.Println (user) / / {{18} {0 {0}} nick 0}}

Tag

In go, the first letter case has a special grammatical meaning and cannot be referenced outside the lowercase package. Due to the need to exchange data with other systems, such as converting to json format. At this time, if you use the attribute name as the key value, it may not necessarily meet the project requirements. Tag uses specific fields as key values when converting to other data formats.

Import "encoding/json" type User struct {Name string `json: "userName" `Age int `json: "userAge" `} func main () {var user User user.Name = "nick" user.Age = 18 conJson, _: = json.Marshal (user) fmt.Println (string (conJson)) / / {"userName": "nick", "userAge": 0}

String ()

If the method String () is implemented, fmt calls String () by default.

Type name1 struct {int string} func (this * name1) String () string {return fmt.Sprintf ("This is String (% s).", this.string)} func main () {n: = new (name1) fmt.Println (n) / / This is String () N.string = "suoning" d: = fmt.Sprintf ("% s", n) / / This is String (suoning). Fmt.Println (d)}

Interface Interface

The Interface type can define a set of methods, but these do not need to be implemented. And interface cannot contain any variables.

The interface type defaults to a pointer.

Interface definition

Type Car interface {NameGet () string Run (n int) Stop ()}

Interface implementation

The interface in Golang does not need to be displayed. As long as a variable contains all the methods in the interface type, the variable implements the interface. Therefore, there is no keyword like implement in golang

If a variable contains multiple methods of type interface, then the variable implements multiple interfaces; if a variable contains only one square part of the interface method, then the variable does not implement the interface.

Empty interface Interface {}: empty interfaces have no methods, so all types implement empty interfaces.

Var an intvar b interface {} / / empty interface b = a

Polymorphisms

Many forms of a thing can be operated according to a unified interface.

Chestnut:

Type Car interface {NameGet () string Run (n int) Stop ()} type BMW struct {Name string} func (this * BMW) NameGet () string {return this.Name} func (this * BMW) Run (n int) {fmt.Printf ("BMW is running of num is% d\ n" N)} func (this * BMW) Stop () {fmt.Printf ("BMW is stop\ n")} type Benz struct {Name string} func (this * Benz) NameGet () string {return this.Name} func (this * Benz) Run (n int) {fmt.Printf ("Benz is running of num is% d\ n") N)} func (this * Benz) Stop () {fmt.Printf ("Benz is stop\ n")} func (this * Benz) ChatUp () {fmt.Printf ("ChatUp\ n")} func main () {var car Car fmt.Println (car) / / var bmw BMW = BMW {Name: "BMW"} car = & bmw fmt.Println (car.NameGet ()) / / BMW car.Run (1) / / BMW is running of num is 1 car .stop () / / BMW is stop benz: = & Benz {Name: "Big Ben"} car = benz fmt.Println (car.NameGet ()) / / Big Ben car.Run (2) / / Benz is running of num is 2 car.Stop () / / Benz is stop / / car.ChatUp () / / ERROR: car.ChatUp undefined (type Car has no field or method ChatUp)}

Interface nesting

One interface can be nested within another interface.

That is, a method that needs to implement two interfaces.

Type Car interface {NameGet () string Run (n int) Stop ()} type Used interface {Car Cheap ()}

Type assertion

Type assertion, because the interface is a general type, the specific type is not known

If you want to convert to a specific type, you can convert it in the following ways:

Var t intvar x interface {} x = ty = x. (int) / / converted to inty, ok = x. (int) / / converted to int without error reporting

Chestnut one:

Func test (I interface {}) {/ / n: = I. (int) n, ok: = I. (int) if! ok {fmt.Println ("error") return} n + = 10 fmt.Println (n)} func main () {var T1 int test (T1)}

Chestnut II:

Switch & typetype Student struct {Name string} func judgmentType (items... interface {}) {for k, v: = range items {switch v. (type) {case string: fmt.Printf ("string,% d [% v]\ n", k, v) case bool: fmt.Printf ("bool,% d [% v]\ n", k, v) case int, int32, int64: fmt.Printf ("int,% d [% v]\ n", k, v) case float32 Float64: fmt.Printf ("float,% d [% v]\ n", k, v) case Student: fmt.Printf ("Student,% d [% v]\ n", k, v) case * Student: fmt.Printf ("Student,% d [% p]\ n", k, v)}} func main () {stu1: = & Student {Name: "nick"} judgmentType (1,2.2, "learing", stu1)}

Chestnut three:

Determine whether a variable implements the specified interface

Type Stringer interface {String () string} type Mystruct interface {} type Mystruct2 struct (this * Mystruct2) String () string {return ""} func main () {var v Mystruct var v2 Mystruct2 v = & v2 if sv, ok: = v. (Stringer); ok {fmt.Printf ("% v implements String ():% s\ n", sv.String ());}}

Reflection reflect

The reflect package implements run-time reflection, allowing programs to manipulate objects of any type.

Typical usage is to save a value with the static type interface {}

Get its dynamic type information by calling TypeOf, which returns a value of type Type.

Calling the ValueOf function returns a value of type Value that represents the data at run time.

Func TypeOf (I interface {}) Type

TypeOf returns the type of value saved in the interface, and TypeOf (nil) returns nil.

Func ValueOf (I interface {}) Value

ValueOf returns a Value,ValueOf (nil) initialized to the specific value held by the I interface and returns a Value zero value.

Reflect.Value.Kind

Gets the category of the variable and returns a constant

Constant returned by the const (Invalid Kind = iota Bool Int Int8 Int16 Int32 Int64 Uint Uint8 Uint16 Uint32 Uint64 Uintptr Float32 Float64 Complex64 Complex128 Array Chan Func Interface Map Ptr Slice String Struct UnsafePointer) reflect.Value.Kind () method

Reflect.Value.Interface ()

Convert to interface {} type

[variable Interface {} Reflect.Value]

Get the value of the variable:

Reflect.ValueOf (x). Int () reflect.ValueOf (x). Float () reflect.ValueOf (x). String () reflect.ValueOf (x). Bool ()

Change the value of a variable by reflection

Reflect.Value.SetXX related methods, such as: reflect.Value.SetInt (), set integer reflect.Value.SetFloat (), set floating point number reflect.Value.SetString (), set string

Chestnut one

Import "reflect" func main () {var x float64 = 5.21 fmt.Println ("type:", reflect.TypeOf (x)) / / type: float64 v: = reflect.ValueOf (x) fmt.Println ("value:", v) / / value: 5.21 fmt.Println ("type:", v.Type ()) / / type: float64 fmt.Println ("kind:", v.Kind ()) / / kind: float64 fmt.Println ("value:" V.Float () / / value: 5.21 fmt.Println (v.Interface ()) / / 5.21 fmt.Printf ("value is% 1.1e\ n", v.Interface ()) / / value is 5.2e+00 y: = v.Interface (). (float64) fmt.Println (y) / / 5.21}

Chestnut II (modify value)

SetXX (x) because it passes a copy of the value of x, SetXX cannot change x. To change x, you must pass a pointer to x, SetXX (& x).

/ / error code! / / panic: reflect: reflect.Value.SetFloat using unaddressable valuefunc main () {var a float64 fv: = reflect.ValueOf (& a) fv.SetFloat (520.00) fmt.Printf ("% v\ n", a)} / / correct, pass the pointer func main () {var a2 float64 fv2: = reflect.ValueOf (& a2) fv2.Elem (). SetFloat (520.00) fmt.Printf ("% v\ n", A2) / / 520}

Reflection operation structure

Reflect.Value.NumField () gets the number of fields in the structure

Reflect.Value.Method (n) .call (nil) to call the method in the structure

Chestnut one (manipulating the structure by reflection)

Import "reflect" type NotknownType struct {S1 string S2 string S3 string} func (n NotknownType) String () string {return n.S1 + "&" + n.S2 + "&" + n.S3} var secret interface {} = NotknownType {"Go", "C" "Python"} func main () {value: = reflect.ValueOf (secret) fmt.Println (value) / Go & C & Python typ: = reflect.TypeOf (secret) fmt.Println (typ) / / main.NotknownType knd: = value.Kind () fmt.Println (knd) / / struct for i: = 0 I < value.NumField (); iTunes + {fmt.Printf ("Field% d:% v\ n", I, value.Field (I))} results: = value.Method (0) .call (nil) fmt.Println (results) / / [Go & C & Python]}

Chestnut II (modify the structure by reflection)

Import "reflect" type T struct {An int B string} func main () {t: = T {18, "nick"} s: = reflect.ValueOf (& t) .Elem () typeOfT: = s.Type () for I: = 0; I < s.NumField () Fmt.Printf + {f: = s.Field (I) fmt.Printf ("% d:% s% s =% v\ n", I, typeOfT.Field (I) .Name, f.Type () F.Interface ()} s.Field (0) .SetInt (25) s.Field (1). SetString ("nicky") fmt.Println (t)} / * output: an int = 181: B string = nick {25 nicky} * / import "reflect" type test struct {S1 string S2 string s 3 string} var s interface {} = & test {S1: "S1", S2: "S2", S2: "S3" } func main () {val: = reflect.ValueOf (s) fmt.Println (val) / / & {S1 S2 S3} fmt.Println (val.Elem ()) / / {S1 S2 S3} fmt.Println (val.Elem (). Field (0)) / / S1 val.Elem (0). SetString ("hehe") / / S1 uppercase}

Chestnut III (internal implementation of struct tag)

Package mainimport ("fmt"reflect") type User struct {Name string `json: "user_name" `} func main () {var user User userType: = reflect.TypeOf (user) jsonString: = userType.Field (0). Tag.Get ("json") fmt.Println (jsonString) / / user_name} the above is an example analysis of Interface reflection of struct interface in Go language. have you learned any knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.

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

Development

Wechat

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

12
Report