首页 > 其他分享 >Go必知必会:深入剖析Go语言中的结构体

Go必知必会:深入剖析Go语言中的结构体

时间:2024-08-04 18:27:34浏览次数:15  
标签:struct 必知 数据类型 访问 内存 必会 Go 结构

Go必知必会:深入剖析Go语言中的结构体 原创 王中阳 王中阳  2024年07月24日 06:03 北京 1人听过 文末有面经共享群 本文来自极客学院专栏,欢迎订阅:Go入门进阶实战专栏:其实学Go很简单。   Go语言以其清晰的语法和强大的内置类型系统,为构建高效且易于维护的软件程序提供了坚实的基础。在Go的数据类型体系中,结构体(struct)扮演着至关重要的角色,它是实现复杂数据模型的关键工具。结构体允许开发者将多个不同类型的数据项有机地组合成一个单一的自定义类型,从而提供了一种强大的方式来封装和抽象数据。   这种数据封装的方式不仅增强了代码的可读性和可维护性,而且促进了代码的模块化和重用。通过结构体,开发者可以创建出清晰、一致且易于理解的数据模型,这对于构建大型软件系统尤为重要。   结构体的概念 在Go语言中,结构体(struct)是一种合成数据类型,它通过将一系列字段(field)组合成一个单一的实体,来实现数据的复合表示。每个字段可以是不同的数据类型,这使得结构体在表示现实世界中的对象时具有极高的灵活性和表现力。   例如,我们可以将一个人抽象为一个结构体,其中包含姓名、年龄、职业等属性。这种抽象不仅使得数据的组织更加直观,而且便于在程序中进行操作和管理。结构体的使用,是Go语言面向对象编程特性的一种体现,它允许开发者以一种类型化和结构化的方式来处理复杂的数据集合。   定义和初始化结构体 在Go语言中定义结构体的基本语法如下:   type Person struct {     Name string     Age int     Country string } 结构体可以通过下面这种方式直接初始化:   p := Person{     Name: "Alice",     Age: 30,     Country: "Wonderland", } 或者使用new函数分配内存并返回指向该结构体的指针:   p := new(Person) p.Name = "Bob" p.Age = 25 访问和修改结构体字段 使用点(.)操作符访问或修改结构体的字段:   fmt.Println(p.Name) // 输出: Alice   p.Age = 31 // 修改Age字段 方法定义 Go语言允许在结构体类型上定义方法,这些方法被称为实例方法:   func (p *Person) Introduce() {     fmt.Printf("Hello, my name is %s and I am from %s.\n", p.Name, p.Country) } 匿名字段和嵌入 结构体可以包含匿名字段,这些字段可以是其他类型的结构体:   type Circle struct {     Center Point     Radius float64 }   type Point struct {     X, Y float64 } 在Circle中,Point作为匿名字段,可以直接通过Circle实例访问X和Y。   标签和反射 结构体的字段可以有标签(tag),通常用于JSON编码、XML编码等:   type Config struct {     Host string `json:"host"`     Port int `json:"port"` } 标签通过reflect包在运行时访问:   reflect.TypeOf(Config{}).Field(0).Tag.Get("json") // 输出: host 结构体和接口 结构体可以被赋予接口,只要它们实现了接口的所有方法:   type Animal interface {     MakeSound() }   type Dog struct{}   func (d Dog) MakeSound() {     fmt.Println("Woof!") }   var myDog Animal = Dog{} myDog.MakeSound() // Woof! 结构体的内存布局 在Go语言中,结构体作为一种合成数据类型,其在内存中的存储是连续的。然而,为了满足特定的内存对齐要求,编译器可能会在结构体的字段之间插入填充字节(padding)。这种内存对齐和填充机制虽然可以提高访问效率,但也可能导致结构体的实际内存占用比字段总和要大。   内存对齐是指按照特定规则调整数据在内存中的存放位置,以确保数据的访问能够符合特定硬件平台的要求,从而提高数据访问的速度。在Go语言中,结构体的每个字段都会根据其数据类型的大小进行对齐,而结构体的总大小也会根据最大的字段对齐要求进行调整。   因此,开发者在设计结构体时,应该考虑到字段的排列顺序和数据类型选择,以优化内存的使用效率和访问性能。   结构体和并发 在Go语言的并发编程实践中,结构体本身并不具备线程安全性。这意味着,如果多个goroutine需要访问同一个结构体实例,而没有采取适当的同步措施,就可能发生数据竞争,导致不可预测的结果。   为了确保并发安全性,开发者应该使用互斥锁(sync.Mutex)或其他同步机制来控制对共享结构体的访问。互斥锁可以确保在任意时刻,只有一个goroutine能够访问结构体的特定部分,从而避免数据竞争和潜在的不一致问题。   使用互斥锁时,开发者应当遵循以下最佳实践:   在访问共享结构体之前,使用mutex.Lock()获取锁; 完成对结构体的访问和修改后,使用mutex.Unlock()释放锁; 避免在持有锁的情况下执行可能导致阻塞的操作,以防止死锁。 通过这些措施,开发者可以有效地保护共享资源,确保并发程序的稳定性和可靠性。   反射和结构体 反射可以用于在运行时检查和修改结构体的字段:   reflect.ValueOf(p).FieldByName("Name").SetString("Charlie") 总结 结构体是Go语言中用于创建自定义数据类型的强大工具。通过本文的深入介绍,你应该能够理解结构体的内存布局、如何定义和初始化结构体、如何通过标签使用反射,以及如何在结构体上定义方法。掌握结构体的使用对于编写有效和可维护的Go代码至关重要。随着你继续学习和实践,将发现结构体在Go语言编程中的广泛应用。   早日上岸! 我们搞了一个免费的面试真题共享群,互通有无,一起刷题进步。   没准能让你能刷到自己意向公司的最新面试题呢。   感兴趣的朋友们可以加我微信:wangzhongyang1993,备注:面试群。   图片 点击下方文章,看看他们是怎么找到好工作的!   这些朋友赢麻了!   我们又出成绩啦!大厂Offer集锦!遥遥领先!   阅读原文 阅读 548   ​  

标签:struct,必知,数据类型,访问,内存,必会,Go,结构
From: https://www.cnblogs.com/cheyunhua/p/18342060

相关文章

  • Jquery正确发送headers值,Django后台request.Meta取值
    jquery发送请求$.ajax({method:"POST",headers:{"Auth_xxx":"yes"},data:{},url:"",success:function(response){console.log("respons......
  • 为什么我在 html 页面的格式化段落中没有收到 google gemini 响应
    我在我的django中使用googlegeminiapi,一切都很顺利,在终端中生成的Gemini响应非常完美,两个段落和所有段落之间都有空格,但是当我将此响应传递到html页面时,所有格式都消失了,那里两段之间没有空格,我不知道为什么它在响应中产生不必要的星星**,请告诉我如何修复它。......
  • go高并发之路——消息中间件kafka(中)
    接着上篇,我们继续聊聊kafka的那些事儿。一、消费者组消费者组,即ConsumerGroup,是Kafka的一大亮点设计。一个组内可以有多个消费者或消费者实例(ConsumerInstance),它们共享一个公共的ID,这个ID被称为GroupID。组内的所有消费者协调在一起来消费订阅主题(topic)的所有分区(Part......
  • 在 Python 中从 HTML 中抓取嵌入的 Google Sheet
    这对我来说相对棘手。我正在尝试提取来自python中的google工作表的嵌入表。这是链接我不拥有该工作表,但它是公开可用的。这是迄今为止我的代码,当我输出标题时,它向我显示“”。任何帮助将不胜感激。最终目标是将此表转换为pandasDF。多谢你们importlx......
  • 使用 django 的 EmailMessage 发送波斯语电子邮件时出现问题
    我对django相当陌生,并尝试使用django.core.mail.EmailMessage发送包含波斯语字母的电子邮件。这是我的代码:fromdjango.core.mailimportEmailMessagefromdjango.confimportsettingsdefcustom_sender(subject:str,body:str,recipient_list:list[str],......
  • 如何使用 Python 在 Google 或 DuckDuckGo 中快速获取答案
    我有一个人工智能助手项目,我希望它在互联网上搜索。我想使用适用于Python的GoogleQuickAnswerBox或DuckDuckGoInstantAnswerAPI。我看到了其他问题,但它们对我没有多大帮助。这是我想要实现的一个示例:问题:什么是长颈鹿?Google的答案:DuckDuckGo的......
  • django增删改查
    1.增classRole(models.Model):title=models.CharField(verbose_name="角色",max_length=32)od=models.IntegerField(verbose_name="排序",default=0)defstr(self):return"{}-{}-{}".format(self.id,self.title,self.od)方法一:obj1......
  • django多数据库操作
    1.读写分离192.168.1.2default主数据库负责写入192.168.1.3slave从数据库负责读取2.生成数据库表pythonmanage.pymakemigrations分别迁移到主从数据库pythonmanage.pymigrate--database=defaultpythonmanage.pymigrate--database=slave多个app分......
  • 前端必知必会-HTMLCanvas图形
    文章目录HTMLCanvas图形添加JavaScript绘制一条线绘制一个圆圈绘制一个文本描边文本绘制线性渐变绘制圆形渐变绘制图像总结HTMLCanvas图形HTML<canvas>元素用于在网页上绘制图形。什么是HTMLCanvas?HTML<canvas>元素用于通过JavaScript动态绘制图形......
  • 前端必知必会-html svg
    文章目录HTMLSVG图形什么是SVG?`<svg>`元素SVG圆形SVG矩形具有不透明度和圆角的SVG矩形SVG星形SVG渐变椭圆和文本SVG和Canvas之间的区别SVG与Canvas的比较总结HTMLSVG图形SVG(可缩放矢量图形)SVG在XML中定义基于矢量图形,可直接嵌入HTML页面。......