日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Go空結構體struct{}的作用是什么_Golang

作者:勁仔Go ? 更新時間: 2023-05-14 編程語言

前言

通過這篇文章《淺談Go結構體的基本使用》,我們初步認識了空結構體,使用unsafe.SizeOf()方法,明確知道了空結構體,它不占用存儲空間(即“寬度”為0,寬度描述了一個類型的實例所占用的存儲空間的字節數)

s := struct{}{}
fmt.Println(unsafe.Sizeof(s)) //0

在項目代碼中,我們經常都會看到空結構體struct{}{}的使用,所以肯定背后有一定的原因。那究竟它有什么作用,適合什么場景使用呢?

作用

因為空結構體不占據內存空間,因此被廣泛作為各種場景下的占位符使用。一是節省資源,二是空結構體本身就具備很強的語義,即這里不需要任何值,僅作為占位符

使用場景

主要使用場景有3個

  • 實現集合類型
  • 實現空通道
  • 實現方法接收者

實現集合類型

Go語言本身是沒有集合類型(Set),通常是使用map來替代

但有個問題,就是集合類型,只需要用到key(鍵),不需要用到value(值)

如果value使用bool來表示,實際會占用1個字節的空間,為了節省空間,這時空結構體就可以大顯身手了

type Set map[int]struct{}

func main() {
  s := make(Set)
  s.add(1)
  s.add(2)
  s.add(3)
  s.remove(2)
  fmt.Println(s.exist(1))
  fmt.Println(s)

  //輸出:
  //true
  //map[1:{} 3:{}]
}
func (s Set) add(num int) {
  s[num] = struct{}{}
}
func (s Set) remove(num int) {
  delete(s, num)
}
func (s Set) exist(num int) bool {
  _, ok := s[num]
  return ok
}

空結構體作為占位符,不會額外增加不必要的內存開銷,很方便的就把問題給解決了

實現空通道

在Go的channel 的使用場景中,常常會遇到通知型 channel,其不需要發送任何數據,只是用于協調 Goroutine 的運行,用于流轉各類狀態或是控制并發情況。

這類情況就特別適合使用空結構體,只做個占位,不浪費內存空間

func main() {
  ch := make(chan struct{})
  go worker(ch)

  // Send a message to a worker.
  ch <- struct{}{}

  // Receive a message from the worker.
  <-ch
  println("AAA")

  //輸出:
  //BBB
  //AAA
}

func worker(ch chan struct{}) {
  // Receive a message from the main program.
  <-ch
  println("BBB")

  // Send a message to the main program.
  close(ch)
}

由于該 channel 使用的是空結構體,因此也不會帶來額外的內存開銷

實現方法接收者

使用結構體類型的變量作為方法接收者,有時結構體可以不包含任何字段屬性。這種情況,可以用int或者string來替代,但它們都會占用內存空間,所以繼續使用空結構體是比較合適的。

并且也有利于未來針對該類型進行公共字段等的增加,容易擴展和維護

type T struct{}

func methodUse() {
  t := T{}
  t.Print()
  t.Print2()

  //輸出:
  //哈哈哈Print
  //哈哈哈Print2
}

func (t T) Print() {
  fmt.Println("哈哈哈Print")
}
func (t T) Print2() {
  fmt.Println("哈哈哈Print2")
}

總結

針對空結構體的作用和使用場景,進行了詳細的講解。在之后的實際項目開發過程中,只用占位不用實際含義,那么我們就都可以使用空結構體,可以極大的節省不必要的內存開銷。

原文鏈接:https://juejin.cn/post/7199265829955223589

欄目分類
最近更新