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

What is the empty structure of Go language

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article mainly shows you "what is the empty structure of Go language". The content is simple and clear. I hope it can help you solve your doubts. Let me lead you to study and learn this article "what is the empty structure of Go language".

What is an empty structure?

We say that structures that do not contain any fields are called short structures, and empty structures can be defined in the following ways:

Original definition

Var a struct {}

Type alias

Type empty struct {} var e empty features the same address

We define two non-empty structure variables and empty structure variables respectively, and then print the address, and find that the address of the empty structure variable is the same:

/ / define a non-empty structure type User struct {name string} func main () {/ / two non-empty structures with different var user1 User var user2 User fmt.Printf ("% p\ n", & user1) / / 0xc000318670 fmt.Printf ("% p\ n", & user2) / / 0xc000318680 / / define two empty structures Same address var first struct {} var second struct {} fmt.Printf ("% p\ n", & first) / / 0x1ca15f0 fmt.Printf ("% p\ n", & second) / / 0x1ca15f0}

We know that the variable passing in Go language is value passing. For the variable address before and after passing parameters should be different, let's try again by passing parameters:

/ / non-empty structure type NonEmptyUser struct {name string} / / empty structure type EmptyUser struct {} / print non-empty structure parameter address func testNonEmptyUser (user NonEmptyUser) {fmt.Printf ("% p\ n", & user)} / / print empty structure parameter address func testEmptyUser (user EmptyUser) {fmt.Printf ("% p\ n") & user)} func main () {/ / two non-empty structures with different variable addresses var user1 NonEmptyUser fmt.Printf ("% p\ n", & user1) / / 0xc0001986c0 testNonEmptyUser (user1) / / 0xc0001986d0 / / two empty structure variables have the same address var user2 EmptyUser fmt.Printf ("% p\ n", & user2) / / 0x1ca25f0 testEmptyUser (user2) / / 0x1ca25f0}

It is found that for non-empty structures, the addresses before and after passing parameters are different, but for empty structure variables, the addresses before and after are the same.

Size is 0

In Go, we can use unsafe.Sizeof to calculate the number of bytes occupied by a variable, so let's take a few examples:

Type EmptyUser struct {} func main () {var i int var s string var m [] string var u EmptyUser fmt.Println (unsafe.Sizeof (I)) / 8 fmt.Println (unsafe.Sizeof (s)) / / 16 fmt.Println (unsafe.Sizeof (m)) / / 24 fmt.Println (unsafe.Sizeof (u)) / / 0}

You can see that the memory space occupied by the empty structure is 0, and for the combination of empty structures, the occupied space is also 0:

/ / probe into the principle of type EmptyUser struct {name struct {} age struct {}} func main () {var u EmptyUser fmt.Println (unsafe.Sizeof (u)) / / 0}

Why are all empty structures with the same address and zero size? let's take a look at the source code (go/src/runtime/malloc.go):

/ / when base address for all 0-byte allocationsvar zerobase uintptr// creates a new object, call mallocgc to allocate memory func newobject (typ * _ type) unsafe.Pointer {return mallocgc (typ.size, typ, true)} func mallocgc (size uintptr, typ * _ type, needzero bool) unsafe.Pointer {if gcphase = = _ GCmarktermination {throw ("mallocgc called with gcphase = = _ GCmarktermination")} if size = = 0 {return unsafe.Pointer (& zerobase)}.}

As you can see from the source code, when you create a new object, you need to call malloc.newobject () for memory allocation, and then call the mallocgc method, in which, if you judge the size==0 of the type, the address of the zerobase is returned. Zerobase is a uintptr global variable that occupies 8 bytes.

So what we can be sure of is that in the go language, all memory allocations for size==0 use the same address, zerobase, so all the empty configuration addresses we saw at the beginning are the same.

Working with scen

If the empty construct does not contain any data, its application scenario should not care about the value content and should only be treated as a placeholder. In this scenario, because it does not take up memory space, the use of empty constructs can not only save space, but also provide semantic support.

Collection (Set)

Students who have used Java should have used Set types. Set is a collection of non-repeating elements, but the Go language does not provide native Set types. But we know that the Map structure stores the key-value type, and key does not allow repetition, so we can use Map to store the data needed by Set,key, and value can give a fixed value. So what is the value of value? At this time, our empty structure can come out, do not take up space, but also complete the occupancy operation, can be called perfect, let's see how to achieve it.

/ / A Set collection of string type type Set map [string] struct {} / / add an element func (s Set) Add (key string) {s [key] = struct {} {}} / / remove an element func (s Set) Remove (key string) {delete (s, key)} / / whether it contains an element func (s Set) Contains (key string) bool {_ Ok: = s [key] return ok} / / initialize func NewSet () Set {s: = make (Set) return s} / / Test uses func main () {set: = NewSet () set.Add ("hello") set.Add ("world") fmt.Println (set.Contains ("hello") set.Remove ("hello") fmt.Println (set.Contains ("hello"))} channel

Empty structure and channel can be described as a classic combination, sometimes we just need a signal to control the running logic of the program, regardless of its content.

In the following example, we define two channel to receive the signal that two tasks are completed, and when the signal is received that the task is completed, the corresponding action will be triggered.

Func doTask1 (ch chan struct {}) {time.Sleep (time.Second) fmt.Println ("do task1") ch

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