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 Go interface

2025-04-06 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

This article introduces the relevant knowledge of "how to use Go interface". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

What is interface?

To put it simply, interface is a combination of a set of method, and we define a set of behaviors of objects through interface.

Interface Typ

The interface type defines a set of methods that an object implements if it implements all the methods of an interface. For detailed syntax, refer to the following example

Type Human struct {name string age int phone string} type Student struct {Human / / anonymous field Human school string loan float32} type Employee struct {Human / / anonymous field Human company string money float32} / / Human object implements the Sayhi method func (h * Human) SayHi () {fmt.Printf ("Hi, I am% s you can call me on% s\ n", h.name H.phone)} / / Human object implements Sing method func (h * Human) Sing (lyrics string) {fmt.Println ("La la, la la la, la la la la la...", lyrics)} / / Human object implements Guzzle method func (h * Human) Guzzle (beerStein string) {fmt.Println ("Guzzle Guzzle Guzzle...", beerStein)} / / Employee overloads Human's Sayhi method func (e * Employee) SayHi () {fmt.Printf ("Hi, I am% s") I work at% s. Call me on% s\ n ", e.name, e.company, e.phone) / / this sentence can be divided into multiple lines} / / Student to implement the BorrowMoney method func (s * Student) BorrowMoney (amount float32) {s.loan + = amount / / (again and again and...)} / / Employee to implement the SpendSalary method func (e * Employee) SpendSalary (amount float32) {e.money-= amount / More vodka examples! Get me through the day!} / / define interfacetype Men interface {SayHi () Sing (lyrics string) Guzzle (beerStein string)} type YoungChap interface {SayHi () Sing (song string) BorrowMoney (amount float32)} type ElderlyGent interface {SayHi () Sing (song string) SpendSalary (amount float32)}

From the above code, we can know that interface can be implemented by arbitrary objects. We see the above Men interface implemented by Human, Student, and Employee. Similarly, an object can implement any number of interface. For example, the above Student implements two interface, Men and YoungChap.

Finally, any type implements an empty interface (as we define it: interface {}), that is, an interface containing 0 method.

Interface value

So what value can be stored in interface? If we define a variable of interface, then any type of object that implements the interface can be stored in this variable. For example, in the above example, we define a variable m of type Men interface, so that the value of Human, Student, or employee can be stored in m.

Because m can hold these three types of objects, we can define a slice that contains Men type elements, and this slice can be assigned to an object of any structure that implements the Men interface, which is different from our traditional sense of slice.

Let's take a look at the following example:

Package mainimport "fmt" type Human struct {name string age int phone string} type Student struct {Human / / anonymous field school string loan float32} type Employee struct {Human / / anonymous field company string money float32} / / Human implement SayHi method func (h Human) SayHi () {fmt.Printf ("Hi, I am% s you can call me on% s\ n", h.name H.phone)} / / Human implement Sing method func (h Human) Sing (lyrics string) {fmt.Println ("La la la la...", lyrics)} / / Employee overload Human's SayHi method func (e Employee) SayHi () {fmt.Printf ("Hi, I am% s, I work at% s. Call me on% s\ n", e.name, e.company, e.phone)} / / Interface Men by Human Student and Employee implement / / because these three types implement these two methods type Men interface {SayHi () Sing (lyrics string)} func main () {mike: = Student {Human {"Mike", 25, "222-222-XXX"}, "MIT", 0.00} paul: = Student {Human {"Paul", 26, "111-222-XXX"}, "Harvard", 100} sam: = Employee {Human {"Sam", 36 "444-222-XXX"}, "Golang Inc.", 1000} tom: = Employee {Human {"Tom", 37, "222-444-XXX"}, "Things Ltd.", 5000} / / the variable i var i Men / / which defines the Men type can store Student I = mike fmt.Println ("This is Mike") A Student: ") i.SayHi () i.Sing (" November rain ") / / I can also store Employee I = tom fmt.Println (" This is tom, an Employee: ") i.SayHi () i.Sing (" Born to be wild ") / / defines slice Men fmt.Println (" Let's use a slice of Men and see what happens ") x: = make ([] Men, 3) / / these three elements are different types of elements. But they implemented the same interface interface x [0], x [1], x [2] = paul, sam, mike for _, value: = range x {value.SayHi ()}}

From the above code, you will find that interface is a collection of abstract methods that must be implemented by other non-interface types rather than self-implementing. Go implements duck-typing through interface: that is, "when you see a bird walking like a duck, swimming like a duck, and barking like a duck, then the bird can be called a duck."

Empty interface

Empty interface (interface {}) does not contain any method, which is why all types implement empty interface. Empty interface doesn't do anything for description (because it doesn't contain any method), but empty interface is useful when we need to store any type of value, because it can store any type of value. It is somewhat similar to the void* type of the C language.

/ / define an as empty interface var an interface {} var i int = 5s: = "Hello world" / / a can store any type of value a = ia = s

If a function takes interface {} as an argument, it can accept any type of value as a parameter, and if a function returns interface {}, it can also return any type of value. Isn't it very useful?

Parameters of interface function

The variables of interface can hold any object that implements the interface type, which gives us some extra thought about whether we can write functions (including method) to accept various types of parameters by defining interface parameters.

For example: fmt.Println is a function we often use, but have you noticed that it can accept any type of data? Open the source file of fmt and you will see a definition like this:

Type Stringer interface {String () string}

That is, any type that implements the String method can be called by fmt.Println as a parameter. Let's give it a try.

Package mainimport ("fmt"strconv") type Human struct {name string age int phone string} / / through this method Human implements fmt.Stringerfunc (h Human) String () string {return "❰" + h. Name + "-" + strconv.Itoa (h.age) + "years-✆" + h. Phone + "❱"} func main () {Bob: = Human {"Bob", 39 "000-7777-XXX"} fmt.Println ("This Human is:", Bob)}

Now if we review the previous Box example, you will find that the Color structure also defines a method:String. In fact, this also implements the interface of fmt.Stringer, that is, if you need a type that can be output in a special format by a fmt package, you must implement the Stringer interface. If this interface is not implemented, fmt will output by default.

/ / implement the same function fmt.Println ("The biggest one is", boxes.BiggestsColor (). String ()) fmt.Println ("The biggest one is", boxes.BiggestsColor ())

Note: objects that implement the error interface (that is, objects that implement Error () string) call the Error () method when using fmt output, so it is no longer necessary to define the String () method.

The type of interface variable storage

We know that interface can store any type of value in its variables (this type implements interface). So how do we know in reverse which type of object is actually stored in this variable? There are two commonly used methods at present:

Comma-ok assertion

There is a syntax in the Go language that can directly determine whether it is a variable of this type: value, ok = element. (T), where value is the value of the variable, ok is a bool type, element is the interface variable, and T is the assertion type.

If the element does store a value of type T, ok returns true, otherwise it returns false.

Let's get a deeper understanding through an example.

Package mainimport ("fmt"strconv") type Element interface {} type List [] Elementtype Person struct {name string age int} / / defines the String method Fmt.Stringerfunc (p Person) String () string {return "(name:" + p.name + "- age:" + strconv.Itoa (p.age) + "years)} func main () {list: = make (List, 3) list [0] = 1 / / an int list [1] =" Hello "/ / a string list [2] = Person {" Dennis ", 70} for index, element: = range list {if value Ok: = element. Int) Ok {fmt.Printf ("list [% d] is an int and its value is% d\ n", index, value)} else if value, ok: = element. (string); ok {fmt.Printf ("list [% d] is a string and its value is% s\ n", index, value)} else if value, ok: = element. (Person) Ok {fmt.Printf ("list [% d] is a Person and its value is% s\ n", index, value)} else {fmt.Printf ("list [% d] is of a different type\ n", index)}

Is it very simple? at the same time, have you noticed more than one if? remember when I introduced the process earlier, if allows initialization of variables.

You may have noticed that the more types we assert, the more if else we have, which is why we introduce switch below.

Switch test

The best explanation is a code example, so let's rewrite the above implementation

Package mainimport ("fmt"strconv") type Element interface {} type List [] Elementtype Person struct {name string age int} / / print func (p Person) String () string {return "(name:" + p.name + "- age:" + strconv.Itoa (p.age) + "years)" func main () {list: = make (List) 3) list [0] = 1 / / an int list [1] = "Hello" / / a string list [2] = Person {"Dennis", 70} for index, element: = range list {switch value: = element. (type) {case int: fmt.Printf ("list [% d] is an int and its value is% d\ n", index Value) case string: fmt.Printf ("list [% d] is a string and its value is% s\ n", index, value) case Person: fmt.Printf ("list [d] is a Person and its value is% s\ n", index, value) default: fmt.Println ("list [% d] is of a different type" Index)}

One thing to emphasize here is that element. (type) syntax cannot be used in any logic outside of switch. If you want to judge a type outside switch, use comma-ok.

Embed interface

What's really attractive about Go is its built-in logic syntax, like the anonymous fields we learn when we learn Struct, how elegant it is, so the same logic is introduced into interface, it's not even more perfect. If an interface1 is an embedded field of interface2, then interface2 implicitly contains the method in interface1.

We can see that there is such a definition in the source code package container/heap

Type Interface interface {sort.Interface / / embedded field sort.Interface Push (x interface {}) / / a Push method to push elements into the heap Pop () interface {} / / a Pop elements that pops elements from the heap}

We see that sort.Interface is actually an embedded field, implicitly including all the method of sort.Interface. That is, the following three methods:

Type Interface interface {/ / Len is the number of elements in the collection. Len () int / / Less returns whether the element with index i should sort / / before the element with index j. Less (I, j int) bool / / Swap swaps the elements with indexes i and j. Swap (I, j int)}

Another example is the io.ReadWriter under the io package, which contains the Reader and Writer interface under the io package:

/ / io.ReadWritertype ReadWriter interface {Reader Writer} reflection

The Go language implements reflection, which is the ability to check the state of a program at run time. The bag we usually use is the reflect bag. How to use the reflect package, the official article explains in detail the implementation principle of the reflect package, laws of reflection

The use of reflect is generally divided into three steps, which are briefly explained below: to reflect a value of a type (these values all implement an empty interface), you first need to convert it to a reflect object (reflect.Type or reflect.Value, calling different functions according to different situations). The two acquisition methods are as follows:

T: = reflect.TypeOf (I) / / get the metadata of the type, through t we can get all the elements in the type definition v: = reflect.ValueOf (I) / / get the actual value, through v we get the value stored in it, and we can also change the value

After converting to a reflect object, we can do some operations, that is, convert the reflect object to the corresponding value, such as

Tag: = t.Elem () .Field (0) .Tag / / get the label name: = v.Elem () .Field (0). String () / / get the value stored in the first field

Get the reflection value and return the corresponding type and value

Var x float64 = 3.4v: = reflect.ValueOf (x) fmt.Println ("type:", v.Type ()) fmt.Println ("kind is float64:", v.Kind () = = reflect.Float64) fmt.Println ("value:", v.Float ())

Finally, in the case of reflection, then the reflected field must be modifiable. we have learned about passing values and references, and the same is true in this. The reflected field must be readable and writable, which means that an error will occur if it is written as follows

Var x float64 = 3.4v: = reflect.ValueOf (x) v.SetFloat

If you want to modify the corresponding value, you must write

Var x float64 = 3.4p: = reflect.ValueOf (& x) v: = p.Elem () v.SetFloat (7.1) the content of "how to use Go interface" ends here. Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

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: 211

*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

Servers

Wechat

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

12
Report