七叶笔记 » golang编程 » 大厂面试必问——Golang中的空struct有什么用

大厂面试必问——Golang中的空struct有什么用

今天说一个小编本人真实经历过的一个面试题目吧。大概是2020年的7月份,是鹅厂的一个面试官问小编的,当场就懵了。小编当时面试的是一个Golang开发岗。题目是: 在Golang中空struct有什么用 。当时小编就蒙了,面试官告诉小编是 主要是做占位符,因为空struct占用的内存是0 。今天小编就和大家好好掰扯掰扯空struct的用法。

首先需要肯定的是面试官的说法,陈述了两个事实。下面我们一一说明。

1,空struct的占用空间为0。

2,空struct主要用作占位符。

空struct占用空间大小

前面呢只是小编说,占用空间为0,有道是耳听为虚,眼见为实,接下来给大家演示一下。在 Golang中,我们可以直接调用 unsafe.Sizeof 计算出一个数据类型占用的字节数。根据下面的结果,显而易见空struct实例不占据任何的内存空间。

 package main

import (
  "fmt"
  "unsafe"
)

func main() {
  struc := unsafe.Sizeof(struct{}{})
  fmt.Println("空struct的大小为:", struc)
}  

空struct的使用场景

空struct的使用的使用场景其实有很多,但是核心只有两点, 作为占位符和不占用内存空间

场景1:实现set

先给各位看官大人说一个简单的场景。比如说小编现在要给所有的粉丝朋友们发money,但是每个用户只能发一次,此时我们就需要记录一下那些用户发放过了。聪明的同学很快就能想到一种常见的数据结构了,譬如说Redis中的Set结构。那么问题来了,我们如果不借用数据库,简单地使用代码能实现吗。答案是肯定的,接下来小编就来给大家演示一下。

我们需要知道的是,实现一个自己的set,最简单的方法就是借用map了。那么小编给大家演示一下使用空struct方法。

 package main

import (
  "fmt"
  "unsafe"
)

type Set map[string]struct{}

func (s Set) Get(key string) bool {
  _, ok := s[key]
  return ok
}

func (s Set) Add(key string) {
  s[key] = struct{}{}
}

func (s Set) Del(key string) {
  delete(s, key)
}

func main() {
  set := make(Set)
  set.Add("不穿格子衫的程序猿1")
  set.Add("不穿格子衫的程序猿2")
  set.Add("不穿格子衫的程序猿3")
  fmt.Println(set.Get("不穿格子衫的程序猿1"))
  fmt.Println(set.Get("不穿格子衫的程序猿2"))
  fmt.Println("Set的大小为:", unsafe.Sizeof(set))
}  

试想一下,用map实现set的时候value值是没有意义的,此时不管使用什么类型,都会占用一定的空间,即使是将值设置为 bool 类型,也会多占1个字节,那假设map中有一百万条数据,就会浪费1MB 的空间。但是使用空struct就不一样了。

场景2:作为无语义信号量

有时候我们使用channel时不需要传递任何数据,只需要通知其他goroutine执行任务即可。比如定时脚本之类的,此时使用空struct作为占位符就很合适了。

 package main

import (
  "fmt"
  "time"
)

func worker(ch chan struct{}) {
  <-ch
  fmt.Println("更多免费资料,关注公众号:不穿格子衫的程序猿。")
  close(ch)
}

func main() {
  ch := make(chan struct{})
  go worker(ch)
  ch <- struct{}{}
  // 防止主线程提前退出
  time.Sleep(1 * time.Second)
}  

其实从理论上讲,还可以有很多种应用方式,只不过那些场景不太常见而已,小编此处就不一一列举了。另外空struct对于Golang的内存对齐也有一定的影响,后续小编会针对这个知识点做详细的解说。

福利赠送

又到了大家期待的福利时间了。本次赠送的是Golang必读书籍50本。

废话不多说,各位看官大人要怎么获取呢。很简单, 关注小编,私信 资料 」即可获得免费获取方式。

如果大家有比较好的资源欢迎相互交流,共同提高。同时有部分素材来源于网络,如侵,联删

相关文章