《Go 简易速速上手小册》第3章:数据结构(2024 最新版)(上)+https://developer.aliyun.com/article/1486986
3.3 结构体与方法:Go 语言的构建块
Ahoy! 在 Go 语言的宝库中,结构体(Struct)是构建复杂数据模型的基石,而方法(Method)则让这些结构体不仅仅是静态的数据集合,而是能够执行操作的实体。就像在乐高世界里,结构体是你手中的积木块,方法则是让积木动起来的魔法。让我们一起探索这些强大的工具,看看如何在 Go 中使用它们来构建和操纵复杂的数据结构。
3.3.1 基础知识讲解
结构体(Struct)
结构体是一种聚合数据类型,它允许你将多个不同类型的项(称为字段)组合成一个单一的复合类型。每个字段都有一个名称和一个类型。
type Person struct { Name string Age int Address string }
方法(Method)
方法是附加到类型上的函数。在 Go 中,你可以为任何类型定义方法,包括结构体类型。方法的定义与函数类似,但它在函数名之前有一个额外的参数,称为接收器(Receiver),表示该方法附加到的类型。
func (p Person) Introduce() { fmt.Printf("Hi, I'm %s, %d years old.\n", p.Name, p.Age) }
3.3.2 重点案例:图书管理系统
在图书管理系统中,我们已经探索了添加图书、搜索图书以及借阅图书的基本功能。现在,我们将进一步扩展这个系统,添加返回图书和列出所有图书的功能,以及实现一个简单的用户界面,让用户可以通过命令行与系统交互。
功能描述
- 添加新书到图书馆。
- 根据书名搜索图书。
- 借阅图书,并更新图书的借阅状态。
- 返回图书,并更新图书的借阅状态。
- 列出图书馆所有图书的信息。
- 实现命令行用户界面。
实现代码
首先,我们将在 Book
和 Library
结构体上添加新的方法,然后创建一个简单的命令行界面来与用户交互。
package main import ( "bufio" "fmt" "os" "strings" ) // Book 定义图书结构体 type Book struct { Title string Author string ISBN string Available bool } // Library 定义图书馆结构体 type Library struct { Collection []Book } // AddBook 添加新书到图书馆 func (l *Library) AddBook(book Book) { l.Collection = append(l.Collection, book) } // FindBook 搜索图书 func (l *Library) FindBook(title string) *Book { for i := range l.Collection { if l.Collection[i].Title == title { return &l.Collection[i] } } return nil } // BorrowBook 借阅图书 func (b *Book) BorrowBook() bool { if b.Available { b.Available = false return true } return false } // ReturnBook 返回图书 func (b *Book) ReturnBook() { b.Available = true } // ListBooks 列出所有图书 func (l *Library) ListBooks() { for _, book := range l.Collection { fmt.Printf("Title: %s, Author: %s, ISBN: %s, Available: %t\n", book.Title, book.Author, book.ISBN, book.Available) } } // 用户界面 func main() { library := Library{} scanner := bufio.NewScanner(os.Stdin) for { fmt.Println("\nWelcome to the Library") fmt.Println("1. Add Book") fmt.Println("2. Find Book") fmt.Println("3. Borrow Book") fmt.Println("4. Return Book") fmt.Println("5. List Books") fmt.Println("6. Exit") fmt.Print("Enter option: ") scanner.Scan() option := scanner.Text() switch option { case "1": fmt.Print("Enter title: ") scanner.Scan() title := scanner.Text() fmt.Print("Enter author: ") scanner.Scan() author := scanner.Text() fmt.Print("Enter ISBN: ") scanner.Scan() isbn := scanner.Text() library.AddBook(Book{Title: title, Author: author, ISBN: isbn, Available: true}) fmt.Println("Book added.") case "2": fmt.Print("Enter title: ") scanner.Scan() title := scanner.Text() book := library.FindBook(title) if book != nil { fmt.Printf("Book found: %+v\n", *book) } else { fmt.Println("Book not found.") } case "3": fmt.Print("Enter title: ") scanner.Scan() title := scanner.Text() book := library.FindBook(title) if book != nil && book.BorrowBook() { fmt.Println("Book borrowed.") } else { fmt.Println("Book not available.") } case "4": fmt.Print("Enter title: ") scanner.Scan() title := scanner.Text() book := library.FindBook(title) if book != nil { book.ReturnBook() fmt.Println("Book returned.") } else { fmt.Println("Book not found.") } case "5": library.ListBooks() case "6": fmt.Println("Goodbye!") return default: fmt.Println("Invalid option.") } } }
通过这个案例的扩展,我们不仅增强了图书管理系统的功能,还实现了一个简单的命令行界面,使用户能够更方便地与系统交互。这种类型的系统可以根据需要进一步扩展,比如添加用户管理、图书预约等功能。掌握了如何构建和扩展这样的系统,你就能在自己的项目中实现更复杂和用户友好的应用程序。
3.3.3 拓展案例 1:员工管理系统
在任何组织中,有效地管理员工信息是至关重要的。通过这个案例,我们将构建一个简易的员工管理系统,使管理员能够添加新员工、更新员工信息、删除员工记录,并查询特定员工的信息。
功能描述
- 添加新员工到系统中。
- 更新现有员工的信息。
- 删除员工记录。
- 查询特定员工的信息。
- 列出系统中所有员工的信息。
实现代码
我们将使用结构体来表示员工信息,并为这个员工管理系统定义一系列方法来处理员工数据。
package main import ( "fmt" ) // Employee 定义员工信息的结构体 type Employee struct { ID string Name string Position string } // EmployeeManager 管理员工信息的结构体 type EmployeeManager struct { employees map[string]Employee } // NewEmployeeManager 创建一个新的员工管理器 func NewEmployeeManager() *EmployeeManager { return &EmployeeManager{employees: make(map[string]Employee)} } // AddEmployee 添加新员工 func (em *EmployeeManager) AddEmployee(id, name, position string) { em.employees[id] = Employee{ID: id, Name: name, Position: position} fmt.Println("成功添加员工:", name) } // UpdateEmployee 更新员工信息 func (em *EmployeeManager) UpdateEmployee(id, name, position string) { if _, exists := em.employees[id]; exists { em.employees[id] = Employee{ID: id, Name: name, Position: position} fmt.Println("成功更新员工信息:", name) } else { fmt.Println("员工不存在:", name) } } // DeleteEmployee 删除员工 func (em *EmployeeManager) DeleteEmployee(id string) { if _, exists := em.employees[id]; exists { delete(em.employees, id) fmt.Println("成功删除员工:", id) } else { fmt.Println("员工不存在:", id) } } // QueryEmployee 查询员工信息 func (em *EmployeeManager) QueryEmployee(id string) { if emp, exists := em.employees[id]; exists { fmt.Printf("员工信息: ID: %s, 姓名: %s, 职位: %s\n", emp.ID, emp.Name, emp.Position) } else { fmt.Println("员工不存在:", id) } } // ListEmployees 列出所有员工 func (em *EmployeeManager) ListEmployees() { fmt.Println("所有员工信息:") for _, emp := range em.employees { fmt.Printf("ID: %s, 姓名: %s, 职位: %s\n", emp.ID, emp.Name, emp.Position) } } func main() { manager := NewEmployeeManager() manager.AddEmployee("001", "Alice", "Software Engineer") manager.AddEmployee("002", "Bob", "Project Manager") manager.UpdateEmployee("001", "Alice Smith", "Senior Software Engineer") manager.QueryEmployee("001") manager.DeleteEmployee("002") manager.ListEmployees() }
扩展功能
在上述基础功能之外,员工管理系统可以进一步扩展,例如:
- 支持按职位或其他属性过滤员工。
- 实现图形化用户界面(GUI)或Web界面,使系统更易于使用。
- 集成到更大的人力资源管理系统中,提供更全面的功能。
通过这个案例的扩展,我们展示了如何使用 Go 语言构建一个简易但功能完整的员工管理系统。这个系统不仅能够满足基本的员工信息管理需求,还具备良好的扩展性,可以根据实际业务需求进行定制和扩展。掌握了如何构建这样的系统,你就能在自己的项目中实现更高效和系统化的员工信息管理。
3.3.4 拓展案例 2:在线商店的购物车
在电子商务领域,购物车是一个核心功能,它允许用户在浏览商品时选择想要购买的商品,并最终进行结算。通过这个案例,我们将构建一个简易的购物车系统,该系统能够添加商品到购物车、删除购物车中的商品、计算购物车中所有商品的总价,并列出购物车中的商品。
功能描述
- 添加商品到购物车。
- 删除购物车中的商品。
- 计算购物车中所有商品的总价。
- 列出购物车中的所有商品。
实现代码
我们将定义一个Product
结构体来表示商品,以及一个Cart
结构体来表示购物车。购物车将包含一个商品切片作为其内容。
package main import ( "fmt" ) // Product 定义商品信息 type Product struct { ID string Name string Price float64 } // Cart 定义购物车 type Cart struct { Products []Product } // NewCart 创建一个新的购物车实例 func NewCart() *Cart { return &Cart{} } // AddProduct 向购物车中添加商品 func (c *Cart) AddProduct(product Product) { c.Products = append(c.Products, product) fmt.Printf("已添加商品 \"%s\" 到购物车\n", product.Name) } // RemoveProduct 从购物车中删除商品 func (c *Cart) RemoveProduct(ID string) { for i, product := range c.Products { if product.ID == ID { c.Products = append(c.Products[:i], c.Products[i+1:]...) fmt.Printf("已从购物车删除商品 \"%s\"\n", product.Name) return } } fmt.Println("未找到商品,无法从购物车删除") } // CalculateTotal 计算购物车中所有商品的总价 func (c *Cart) CalculateTotal() float64 { var total float64 for _, product := range c.Products { total += product.Price } return total } // ListProducts 列出购物车中的所有商品 func (c *Cart) ListProducts() { fmt.Println("购物车中的商品:") for _, product := range c.Products { fmt.Printf("ID: %s, 名称: %s, 价格: %.2f\n", product.ID, product.Name, product.Price) } } func main() { cart := NewCart() cart.AddProduct(Product{ID: "001", Name: "Go语言圣经", Price: 56.00}) cart.AddProduct(Product{ID: "002", Name: "键盘", Price: 199.00}) cart.ListProducts() fmt.Printf("购物车总价: %.2f\n", cart.CalculateTotal()) cart.RemoveProduct("001") cart.ListProducts() }
扩展功能
在上述基础功能之外,购物车系统可以进一步扩展,例如:
- 支持商品数量的增减,而不仅仅是添加或删除商品。
- 实现优惠券或折扣功能,自动计算折后价格。
- 集成到在线支付系统,支持一键结算功能。
通过这个案例的扩展,我们演示了如何使用 Go 语言构建一个简易但功能完整的购物车系统。这个系统不仅适用于小型或个人项目,也可以作为更大电子商务系统中的一个模块。掌握了如何构建这样的系统,你就能在自己的电商项目中实现更高效和用户友好的购物体验。