go语言中空结构体的实现

 更新时间:2025年04月14日 09:13:42   作者:Achilles.Wang  
本文主要介绍了go语言中空结构体的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

本文主要介绍了go语言中空结构体的实现,具体如下:

在这里插入图片描述

空结构体(struct{})

  • 普通理解

在结构体中,可以包裹一系列与对象相关的属性,但若该对象没有属性呢?那它就是一个空结构体。

空结构体,和正常的结构体一样,可以接收方法函数。

type Lamp struct{}

func (l Lamp) On() {
        println("On")

}
func (l Lamp) Off() {
        println("Off")
}
  • 空结构体的妙用

空结构体的表象特征,就是没有任何属性,而从更深层次的角度来说,空结构体是一个不占用空间的对象。

使用 unsafe.Sizeof 可以轻易的验证这个结果

type Lamp struct{}

func main() {
    lamp := Lamp{}
    fmt.Print(unsafe.Sizeof(lamp))
}
// output: 0

基于这个特性,在一些特殊的场合之下,可以用做占位符使用,合理的使用空结构体,会减小程序的内存占用空间。

比如在使用信道(channel)控制并发时,我们只是需要一个信号,但并不需要传递值,这个时候,也可以使用 struct{} 代替。

func main() {
    ch := make(chan struct{}, 1)
    go func() {
        <-ch
        // do something
    }()
    ch <- struct{}{}
    // ...
}

在 Go 语言中,使用空结构体(struct{})作为通道(chan)的元素类型是一种常见的优化手段。这种做法主要出于以下几个原因:

  • 节省内存空结构体 struct{} 在 Go 中不占用任何内存空间(大小为 0 字节)。因此,当你需要一个通道来传递信号或同步协程时,使用空结构体可以避免不必要的内存开销。

  • 信号传递在某些场景下,你并不需要通过通道传递具体的数据,而只是需要一个简单的信号机制来通知其他协程某个事件已经发生。例如,用于关闭多个工作协程、通知某个操作完成等。此时,空结构体作为通道的元素类型非常合适。

  • 提高性能由于空结构体不占用内存,发送和接收空结构体的操作通常比发送和接收复杂数据类型的通道更快。虽然这种差异在大多数情况下是微不足道的,但在高并发或高性能要求的场景下,这些细微的优化可能会产生显著的影响。

.关闭多个工作协程

package main

import (
    "fmt"
    "time"
)

func worker(id int, done chan struct{}) {
    for {
        select {
        case <-done:
            fmt.Printf("Worker %d shutting down\n", id)
            return
        default:
            fmt.Printf("Worker %d working\n", id)
            time.Sleep(500 * time.Millisecond)
        }
    }
}

func main() {
    done := make(chan struct{})
    numWorkers := 3

    // 启动多个工作协程
    for i := 1; i <= numWorkers; i++ {
        go worker(i, done)
    }

    // 模拟一些工作
    time.Sleep(2 * time.Second)

    // 发送关闭信号
    close(done)

    // 等待一段时间以确保所有工作协程都已退出
    time.Sleep(1 * time.Second)
}

在这个例子中,done 通道被用来通知所有工作协程停止工作。我们不需要通过通道传递任何实际的数据,只需要一个信号即可。

.同步操作完成

package main

import (
    "fmt"
    "sync"
)

func task(id int, wg *sync.WaitGroup, done chan struct{}) {
    defer wg.Done()
    fmt.Printf("Task %d completed\n", id)
    done <- struct{}{} // 发送一个空结构体表示任务完成
}

func main() {
    var wg sync.WaitGroup
    done := make(chan struct{}, 3) // 缓冲区大小为任务数量

    for i := 1; i <= 3; i++ {
        wg.Add(1)
        go task(i, &wg, done)
    }

    // 等待所有任务完成
    go func() {
        wg.Wait()
        close(done)
    }()

    // 接收所有完成信号
    for range done {
        fmt.Println("Received completion signal")
    }

    fmt.Println("All tasks completed")
}

在这个例子中,每个任务完成后都会向 done 通道发送一个空结构体,表示任务已完成。主协程通过读取 done 通道中的信号来确认所有任务是否已完成。

到此这篇关于go语言中空结构体的实现的文章就介绍到这了,更多相关go语言 空结构体内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Go语言并发之WaitGroup的用法详解

    Go语言并发之WaitGroup的用法详解

    这篇文章主要详细介绍了Go语言并发中得到WaitGroup,文中有相关的代码示例供大家参考,对我们的学习或工作有一定的参考价值,感兴趣的同学跟着小编一起来学习吧
    2023-06-06
  • golang包快速生成base64验证码的方法

    golang包快速生成base64验证码的方法

    这篇文章主要介绍了golang包快速生成base64验证码的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • golang中context的作用详解

    golang中context的作用详解

    这篇文章主要介绍了golang中context的作用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Golang通道阻塞情况与通道无阻塞实现小结

    Golang通道阻塞情况与通道无阻塞实现小结

    本文主要介绍了Golang通道阻塞情况与通道无阻塞实现小结,详细解析了通道的类型、操作方法以及垃圾回收机制,从基础概念到高级应用,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Golang内存分配机制详解

    Golang内存分配机制详解

    Go 语言的内存分配机制是理解和优化 Go 程序性能的关键,在 Go 中,内存管理是自动进行的,这得益于 Go 的垃圾回收机制,了解内存如何分配和回收,可以帮助我们写出更高性能的代码,本文将深入讲解下 Go 内存分配机制,需要的朋友可以参考下
    2023-12-12
  • 从源码深入理解golang RWMutex读写锁操作

    从源码深入理解golang RWMutex读写锁操作

    这篇文章主要介绍了从源码深入理解golang RWMutex读写锁操作,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • gin自定义中间件解决requestBody不可重复读问题(最新推荐)

    gin自定义中间件解决requestBody不可重复读问题(最新推荐)

    这篇文章主要介绍了gin自定义中间件解决requestBody不可重复读问题,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-04-04
  • Go时间格式化的实现

    Go时间格式化的实现

    本文主要介绍了Go时间格式化的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • Go语言常见错误之any没传递任何信息解决分析

    Go语言常见错误之any没传递任何信息解决分析

    Go语言,由于其高效强大的并行处理能力和优雅简单的设计哲学,一直以来都是编程世界的宠儿,然而,对于一些Go新手和甚至熟悉Go的程序员也可能会遇到一个常见的错误: any没传递任何信息,那么,如何规避这个错误,本文将揭示其中的秘密
    2024-01-01
  • Go语言实现运算符重载的方法详解

    Go语言实现运算符重载的方法详解

    这篇文章主要为大家详细介绍了如何利用Go语言实现运算符重载的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-09-09

最新评论