首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
复杂数据类型
值类型和指针类型
值类型和指针类型的存储结构
为什么要区分值类型和指针类型
关于引用类型
slice(切片)的使用及实现原理
切片如何实现大小可变
切片的声明和定义
切片长度的扩展
切片容量的扩展
切片参数的复制
利用数组创建切片
利用切片创建切片
切片元素的修改
切片的循环处理
切片索引越界
总结切片操作的底层原理
map(映射)的使用及实现原理
声明和创建map
遍历map中的元素
元素查找与避免二义性
删除元素
map的存储结构解析
map元素的定位原理解析
map的容量扩展原理解析
channel(通道)的使用及实现原理
channel的使用
channel的实现原理
channel与消息队列、协程通信的对比
自定义结构体
自定义数据类型和自定义结构体
自定义结构体的使用
利用new创建实例
从自定义结构体看访问权限控制
自描述的访问权限
编程范例——结构体使用实例
利用自定义结构体实现bitmap
利用timer.Ticker实现定时任务
流程控制
分支控制
if语句实现分支控制
switch语句实现分支控制
分支控制的本质是向下跳转
避免多层if嵌套的技巧
循环控制
for循环
for-range循环
循环控制的本质是向上跳转
循环和递归的区别
跳转控制
goto关键字的使用
goto的本质是任意跳转
编程范例——流程控制的灵活使用
for循环的误区
switch-case的灵活使用
当前位置:
首页>>
技术小册>>
深入浅出Go语言核心编程(二)
小册名称:深入浅出Go语言核心编程(二)
### 编程范例——结构体使用实例 在《深入浅出Go语言核心编程(二)》中,深入探讨Go语言的结构体(Structs)是一个不可或缺的部分。结构体是Go语言中复合数据类型的一种,它允许你将多个不同类型的变量组合成一个单一的类型。这种特性使得结构体在定义复杂的数据模型、实现面向对象编程范式中的类和对象概念时,显得尤为强大和灵活。本章节将通过一系列编程范例,展示结构体在Go语言中的实际应用,帮助读者深入理解并掌握结构体的使用技巧。 #### 一、基础概念回顾 在深入实例之前,简要回顾一下结构体的基础概念是必要的。结构体通过`type`关键字和`struct`标签定义,内部可以包含多个不同类型的字段(Field)。定义结构体时,需要明确每个字段的名称和类型。例如: ```go type Person struct { Name string Age int Email string IsAlive bool } ``` 这里,`Person`是一个结构体类型,它包含四个字段:`Name`(字符串类型)、`Age`(整型)、`Email`(字符串类型)和`IsAlive`(布尔类型)。 #### 二、结构体实例化与初始化 **2.1 直接赋值** 结构体实例化后,可以通过点(`.`)操作符访问其字段并赋值。 ```go var person1 Person person1.Name = "Alice" person1.Age = 30 person1.Email = "alice@example.com" person1.IsAlive = true fmt.Println(person1) // 输出:{Alice 30 alice@example.com true} ``` **2.2 结构体字面量** 更常见的初始化方式是使用结构体字面量,它允许在创建实例时直接初始化所有或部分字段。 ```go person2 := Person{ Name: "Bob", Age: 25, Email: "bob@example.com", IsAlive: true, } fmt.Println(person2) // 输出:{Bob 25 bob@example.com true} ``` 如果字段名具有唯一性,或者你在使用结构体字面量时愿意按定义顺序指定值,还可以省略字段名,但这会降低代码的可读性。 ```go person3 := Person{"Charlie", 28, "charlie@example.com", false} fmt.Println(person3) // 输出:{Charlie 28 charlie@example.com false} ``` **2.3 使用`new`关键字** `new`关键字为结构体分配内存并返回指向该内存的指针,但不会自动初始化字段。 ```go personPtr := new(Person) personPtr.Name = "David" fmt.Println(*personPtr) // 输出:{David 0 false} ``` 注意,直接使用`new`后,除显式初始化的字段外,其他字段将保持其类型的零值。 #### 三、结构体的高级应用 **3.1 嵌套结构体** 结构体可以包含其他结构体作为字段,这种结构称为嵌套结构体。 ```go type Address struct { Street string City string Country string } type Employee struct { Person ID int Address Address Positions []string } // 使用嵌套结构体 emp := Employee{ Person: Person{ Name: "Eve", Age: 32, Email: "eve@example.com", IsAlive: true, }, ID: 12345, Address: Address{"123 Elm St", "Somewhere", "USA"}, Positions: []string{"Engineer", "Manager"}, } fmt.Println(emp) // 注意:直接打印可能不会按预期显示所有字段,因为Go的fmt包默认不会递归打印结构体。 ``` **3.2 结构体方法与接口** Go语言支持为结构体定义方法,这是实现面向对象编程中多态性的关键。结构体方法与函数类似,但有一个额外的接收者参数,该参数表示调用方法的实例。 ```go func (p Person) Introduce() { fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age) } // 使用 person2.Introduce() // 输出:Hello, my name is Bob and I am 25 years old. ``` 通过为不同的结构体实现相同的接口方法,可以实现多态。接口是Go语言中另一种重要的类型,它定义了一组方法,但不实现它们,由具体的类型来实现。 **3.3 结构体与JSON** 在Web开发中,经常需要将Go语言中的结构体序列化为JSON格式,或从JSON反序列化为Go结构体。Go标准库中的`encoding/json`包提供了这一功能。 ```go import "encoding/json" // 序列化 jsonData, err := json.Marshal(person2) if err != nil { log.Fatalf("JSON marshaling failed: %s", err) } fmt.Println(string(jsonData)) // 反序列化 var personFromJson Person err = json.Unmarshal(jsonData, &personFromJson) if err != nil { log.Fatalf("JSON unmarshaling failed: %s", err) } fmt.Println(personFromJson) ``` #### 四、实战范例:图书管理系统 假设我们正在开发一个简单的图书管理系统,我们可以使用结构体来定义图书(Book)和作者(Author)的数据模型。 ```go type Author struct { Name string Birth int Country string } type Book struct { Title string ISBN string Authors []Author PubYear int Pages int Price float64 } // 实例化并初始化 book := Book{ Title: "Go语言编程", ISBN: "978-7-115-53207-2", Authors: []Author{{Name: "Alice", Birth: 1980, Country: "China"}}, PubYear: 2021, Pages: 300, Price: 69.8, } // 假设需要打印图书的详细信息 func PrintBookInfo(b Book) { fmt.Printf("Book Title: %s\n", b.Title) fmt.Printf("ISBN: %s\n", b.ISBN) for _, author := range b.Authors { fmt.Printf("Author: %s, Born in %d, Country: %s\n", author.Name, author.Birth, author.Country) } fmt.Printf("Publication Year: %d\n", b.PubYear) fmt.Printf("Pages: %d\n", b.Pages) fmt.Printf("Price: %.2f\n", b.Price) } // 使用 PrintBookInfo(book) ``` 通过上述范例,我们不仅展示了结构体在定义复杂数据模型时的强大能力,还演示了如何结合使用结构体、切片、循环以及函数来实现具体的业务逻辑。 #### 结语 结构体是Go语言中一个极其重要且强大的特性,它使得我们能够以面向对象的方式组织和操作数据。通过本章节的编程范例,我们深入探讨了结构体的基本用法、高级特性以及在实际项目中的应用。希望这些示例能够帮助读者更好地理解并掌握结构体的使用,进而在Go语言编程中更加得心应手。
上一篇:
自描述的访问权限
下一篇:
利用自定义结构体实现bitmap
该分类下的相关小册推荐:
深入浅出Go语言核心编程(一)
Go Web编程(中)
Golang修炼指南
go编程权威指南(一)
Golang并发编程实战
go编程权威指南(四)
Go 组件设计与实现
Go开发基础入门
Go开发权威指南(下)
WebRTC音视频开发实战
Go-Web编程实战
Go开发权威指南(上)