第五章:数组、切片与映射
5.1 数组
数组基础
package main
import "fmt"
func main() {
// 数组声明
var arr1 [5]int
fmt.Printf("arr1: %v, 长度: %d\\n", arr1, len(arr1))
// 数组初始化
arr2 := [5]int{1, 2, 3, 4, 5}
fmt.Printf("arr2: %v\\n", arr2)
// 自动推断长度
arr3 := […]int{1, 2, 3, 4, 5}
fmt.Printf("arr3: %v, 长度: %d\\n", arr3, len(arr3))
// 指定索引初始化
arr4 := [5]int{1: 10, 3: 30}
fmt.Printf("arr4: %v\\n", arr4)
// 二维数组
matrix := [3][3]int{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9},
}
fmt.Println("二维数组:")
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
fmt.Printf("%d ", matrix[i][j])
}
fmt.Println()
}
// 数组遍历
fmt.Println("\\n数组遍历:")
for i, v := range arr2 {
fmt.Printf("索引: %d, 值: %d\\n", i, v)
}
// 数组是值类型
arr5 := [3]int{1, 2, 3}
arr6 := arr5
arr6[0] = 100
fmt.Printf("\\narr5: %v\\n", arr5)
fmt.Printf("arr6: %v\\n", arr6)
// 数组比较
a := [3]int{1, 2, 3}
b := [3]int{1, 2, 3}
c := [3]int{1, 2, 4}
fmt.Printf("\\na == b: %v\\n", a == b)
fmt.Printf("a == c: %v\\n", a == c)
}
5.2 切片
切片基础
package main
import "fmt"
func main() {
// 切片声明
var s1 []int
fmt.Printf("s1: %v, 长度: %d, 容量: %d\\n", s1, len(s1), cap(s1))
// 切片初始化
s2 := []int{1, 2, 3, 4, 5}
fmt.Printf("s2: %v, 长度: %d, 容量: %d\\n", s2, len(s2), cap(s2))
// 使用make创建切片
s3 := make([]int, 5) // 长度5,容量5
s4 := make([]int, 3, 10) // 长度3,容量10
fmt.Printf("s3: %v, 长度: %d, 容量: %d\\n", s3, len(s3), cap(s3))
fmt.Printf("s4: %v, 长度: %d, 容量: %d\\n", s4, len(s4), cap(s4))
// 从数组创建切片
arr := [5]int{1, 2, 3, 4, 5}
s5 := arr[1:3] // [2, 3]
s6 := arr[:3] // [1, 2, 3]
s7 := arr[2:] // [3, 4, 5]
s8 := arr[:] // [1, 2, 3, 4, 5]
fmt.Printf("s5: %v\\n", s5)
fmt.Printf("s6: %v\\n", s6)
fmt.Printf("s7: %v\\n", s7)
fmt.Printf("s8: %v\\n", s8)
}
切片操作
package main
import "fmt"
func main() {
// 切片追加
s := []int{1, 2, 3}
fmt.Printf("原始切片: %v\\n", s)
s = append(s, 4)
fmt.Printf("追加4: %v\\n", s)
s = append(s, 5, 6, 7)
fmt.Printf("追加5,6,7: %v\\n", s)
// 追加另一个切片
s2 := []int{8, 9, 10}
s = append(s, s2…)
fmt.Printf("追加另一个切片: %v\\n", s)
// 切片复制
src := []int{1, 2, 3, 4, 5}
dst := make([]int, 3)
n := copy(dst, src)
fmt.Printf("复制了%d个元素: %v\\n", n, dst)
// 切片删除元素
s3 := []int{1, 2, 3, 4, 5}
// 删除索引2的元素
s3 = append(s3[:2], s3[3:]…)
fmt.Printf("删除索引2: %v\\n", s3)
// 切片插入元素
s4 := []int{1, 2, 4, 5}
// 在索引2插入3
s4 = append(s4[:2+1], s4[2:]…)
s4[2] = 3
fmt.Printf("插入3: %v\\n", s4)
// 切片反转
s5 := []int{1, 2, 3, 4, 5}
for i, j := 0, len(s5)–1; i < j; i, j = i+1, j–1 {
s5[i], s5[j] = s5[j], s5[i]
}
fmt.Printf("反转: %v\\n", s5)
}
切片深入理解
package main
import "fmt"
func main() {
// 切片扩容机制
s := make([]int, 0)
fmt.Printf("初始 – 长度: %d, 容量: %d\\n", len(s), cap(s))
for i := 0; i < 10; i++ {
s = append(s, i)
fmt.Printf("添加%d – 长度: %d, 容量: %d\\n", i, len(s), cap(s))
}
// 切片共享底层数组
arr := [5]int{1, 2, 3, 4, 5}
s1 := arr[1:3] // [2, 3]
s2 := arr[2:4] // [3, 4]
fmt.Printf("\\narr: %v\\n", arr)
fmt.Printf("s1: %v\\n", s1)
fmt.Printf("s2: %v\\n", s2)
// 修改s1会影响arr和s2
s1[1] = 30
fmt.Printf("\\n修改s1[1]为30后:\\n")
fmt.Printf("arr: %v\\n", arr)
fmt.Printf("s1: %v\\n", s1)
fmt.Printf("s2: %v\\n", s2)
// 使用copy创建独立切片
s3 := make([]int, len(s1))
copy(s3, s1)
s3[0] = 100
fmt.Printf("\\n复制后修改s3[0]为100:\\n")
fmt.Printf("s1: %v\\n", s1)
fmt.Printf("s3: %v\\n", s3)
// 切片作为函数参数
fmt.Println("\\n切片作为函数参数:")
data := []int{1, 2, 3, 4, 5}
fmt.Printf("修改前: %v\\n", data)
modifySlice(data)
fmt.Printf("修改后: %v\\n", data)
}
func modifySlice(s []int) {
s[0] = 100
s = append(s, 6) // 不会影响原切片
fmt.Printf("函数内: %v\\n", s)
}
5.3 映射(Map)
Map基础
package main
import "fmt"
func main() {
// Map声明
var m1 map[string]int
fmt.Printf("m1: %v, 长度: %d\\n", m1, len(m1))
// Map初始化
m2 := map[string]int{
"语文": 90,
"数学": 85,
"英语": 92,
}
fmt.Printf("m2: %v\\n", m2)
// 使用make创建
m3 := make(map[string]int)
m3["语文"] = 90
m3["数学"] = 85
fmt.Printf("m3: %v\\n", m3)
// Map操作
// 添加/修改元素
m3["英语"] = 92
m3["语文"] = 95 // 修改已存在的键
fmt.Printf("添加/修改后: %v\\n", m3)
// 获取元素
score := m3["数学"]
fmt.Printf("数学成绩: %d\\n", score)
// 检查键是否存在
if val, ok := m3["物理"]; ok {
fmt.Printf("物理成绩: %d\\n", val)
} else {
fmt.Println("物理成绩不存在")
}
// 删除元素
delete(m3, "英语")
fmt.Printf("删除英语后: %v\\n", m3)
// 遍历Map
fmt.Println("\\n遍历Map:")
for subject, score := range m2 {
fmt.Printf("%s: %d\\n", subject, score)
}
// Map长度
fmt.Printf("\\nMap长度: %d\\n", len(m2))
}
Map高级用法
package main
import (
"fmt"
"sort"
)
func main() {
// Map的值是切片
students := map[string][]int{
"张三": {90, 85, 92},
"李四": {88, 95, 80},
"王五": {95, 90, 88},
}
fmt.Println("学生成绩:")
for name, scores := range students {
total := 0
for _, score := range scores {
total += score
}
avg := float64(total) / float64(len(scores))
fmt.Printf("%s: %v, 平均分: %.2f\\n", name, scores, avg)
}
// Map的值是Map
classScores := map[string]map[string]int{
"一班": {
"张三": 90,
"李四": 85,
},
"二班": {
"王五": 95,
"赵六": 88,
},
}
fmt.Println("\\n班级成绩:")
for class, scores := range classScores {
fmt.Printf("%s:\\n", class)
for name, score := range scores {
fmt.Printf(" %s: %d\\n", name, score)
}
}
// Map的键排序
m := map[string]int{
"c": 3,
"a": 1,
"b": 2,
"d": 4,
}
// 获取所有键
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
fmt.Println("\\n按key排序:")
for _, k := range keys {
fmt.Printf("%s: %d\\n", k, m[k])
}
// Map实现计数器
text := "hello world hello go hello world"
wordCount := make(map[string]int)
for _, word := range splitWords(text) {
wordCount[word]++
}
fmt.Println("\\n词频统计:")
for word, count := range wordCount {
fmt.Printf("%s: %d\\n", word, count)
}
// Map实现集合
set1 := map[string]bool{
"apple": true,
"banana": true,
"cherry": true,
}
set2 := map[string]bool{
"banana": true,
"cherry": true,
"durian": true,
}
// 交集
intersection := make(map[string]bool)
for k := range set1 {
if set2[k] {
intersection[k] = true
}
}
fmt.Printf("\\n交集: %v\\n", intersection)
// 并集
union := make(map[string]bool)
for k := range set1 {
union[k] = true
}
for k := range set2 {
union[k] = true
}
fmt.Printf("并集: %v\\n", union)
// 差集
diff := make(map[string]bool)
for k := range set1 {
if !set2[k] {
diff[k] = true
}
}
fmt.Printf("差集: %v\\n", diff)
}
// 简单的分词函数
func splitWords(text string) []string {
words := []string{}
word := ""
for _, ch := range text {
if ch == ' ' {
if word != "" {
words = append(words, word)
word = ""
}
} else {
word += string(ch)
}
}
if word != "" {
words = append(words, word)
}
return words
}
5.4 实战案例:图书管理系统
package main
import (
"fmt"
"sort"
"strings"
"time"
)
// Book 图书结构体
type Book struct {
ISBN string
Title string
Author string
Price float64
Quantity int
}
// Library 图书馆结构体
type Library struct {
Books map[string]*Book
Borrowers map[string][]string // 借阅者 -> 借阅的ISBN列表
}
// NewLibrary 创建新图书馆
func NewLibrary() *Library {
return &Library{
Books: make(map[string]*Book),
Borrowers: make(map[string][]string),
}
}
// AddBook 添加图书
func (l *Library) AddBook(book *Book) {
l.Books[book.ISBN] = book
}
// RemoveBook 删除图书
func (l *Library) RemoveBook(isbn string) bool {
if _, ok := l.Books[isbn]; ok {
delete(l.Books, isbn)
return true
}
return false
}
// SearchByTitle 按标题搜索
func (l *Library) SearchByTitle(title string) []*Book {
result := make([]*Book, 0)
for _, book := range l.Books {
if strings.Contains(strings.ToLower(book.Title), strings.ToLower(title)) {
result = append(result, book)
}
}
return result
}
// SearchByAuthor 按作者搜索
func (l *Library) SearchByAuthor(author string) []*Book {
result := make([]*Book, 0)
for _, book := range l.Books {
if strings.Contains(strings.ToLower(book.Author), strings.ToLower(author)) {
result = append(result, book)
}
}
return result
}
// BorrowBook 借阅图书
func (l *Library) BorrowBook(isbn, borrower string) error {
book, ok := l.Books[isbn]
if !ok {
return fmt.Errorf("图书不存在: %s", isbn)
}
if book.Quantity <= 0 {
return fmt.Errorf("图书库存不足: %s", book.Title)
}
book.Quantity—
l.Borrowers[borrower] = append(l.Borrowers[borrower], isbn)
return nil
}
// ReturnBook 归还图书
func (l *Library) ReturnBook(isbn, borrower string) error {
book, ok := l.Books[isbn]
if !ok {
return fmt.Errorf("图书不存在: %s", isbn)
}
// 检查借阅记录
books, ok := l.Borrowers[borrower]
if !ok {
return fmt.Errorf("借阅者不存在: %s", borrower)
}
found := false
for i, b := range books {
if b == isbn {
l.Borrowers[borrower] = append(books[:i], books[i+1:]…)
found = true
break
}
}
if !found {
return fmt.Errorf("借阅记录不存在: %s", isbn)
}
book.Quantity++
return nil
}
// GetBooksByPrice 按价格排序获取图书
func (l *Library) GetBooksByPrice(ascending bool) []*Book {
books := make([]*Book, 0, len(l.Books))
for _, book := range l.Books {
books = append(books, book)
}
sort.Slice(books, func(i, j int) bool {
if ascending {
return books[i].Price < books[j].Price
}
return books[i].Price > books[j].Price
})
return books
}
// GetStatistics 获取统计信息
func (l *Library) GetStatistics() (totalBooks int, totalValue float64, topBorrowers []string) {
for _, book := range l.Books {
totalBooks += book.Quantity
totalValue += book.Price * float64(book.Quantity)
}
// 获取借阅次数最多的前3名
type borrowerCount struct {
Name string
Count int
}
borrowers := make([]borrowerCount, 0)
for name, books := range l.Borrowers {
borrowers = append(borrowers, borrowerCount{name, len(books)})
}
sort.Slice(borrowers, func(i, j int) bool {
return borrowers[i].Count > borrowers[j].Count
})
for i := 0; i < 3 && i < len(borrowers); i++ {
topBorrowers = append(topBorrowers, fmt.Sprintf("%s (%d本)", borrowers[i].Name, borrowers[i].Count))
}
return
}
// PrintAllBooks 打印所有图书
func (l *Library) PrintAllBooks() {
fmt.Println(strings.Repeat("=", 70))
fmt.Println("图书馆藏书列表")
fmt.Println(strings.Repeat("=", 70))
books := l.GetBooksByPrice(true)
for i, book := range books {
fmt.Printf("%d. [%s] %s – %s\\n", i+1, book.ISBN, book.Title, book.Author)
fmt.Printf(" 价格: ¥%.2f, 库存: %d\\n", book.Price, book.Quantity)
}
fmt.Println(strings.Repeat("=", 70))
}
func main() {
// 创建图书馆
lib := NewLibrary()
// 添加图书
lib.AddBook(&Book{
ISBN: "978-7-111-54305-4",
Title: "Go语言实战",
Author: "William Kennedy",
Price: 79.00,
Quantity: 5,
})
lib.AddBook(&Book{
ISBN: "978-7-115-48968-6",
Title: "Go语言高级编程",
Author: "柴树杉",
Price: 89.00,
Quantity: 3,
})
lib.AddBook(&Book{
ISBN: "978-7-111-55828-8",
Title: "Go Web编程",
Author: "谢孟军",
Price: 69.00,
Quantity: 4,
})
lib.AddBook(&Book{
ISBN: "978-7-115-48968-7",
Title: "Go语言圣经",
Author: "Alan Donovan",
Price: 99.00,
Quantity: 2,
})
// 打印所有图书
lib.PrintAllBooks()
// 借阅图书
fmt.Println("\\n借阅图书:")
err := lib.BorrowBook("978-7-111-54305-4", "张三")
if err != nil {
fmt.Println("借阅失败:", err)
} else {
fmt.Println("张三借阅了《Go语言实战》")
}
err = lib.BorrowBook("978-7-111-54305-4", "李四")
if err != nil {
fmt.Println("借阅失败:", err)
} else {
fmt.Println("李四借阅了《Go语言实战》")
}
// 归还图书
fmt.Println("\\n归还图书:")
err = lib.ReturnBook("978-7-111-54305-4", "张三")
if err != nil {
fmt.Println("归还失败:", err)
} else {
fmt.Println("张三归还了《Go语言实战》")
}
// 搜索图书
fmt.Println("\\n搜索'Go'相关图书:")
results := lib.SearchByTitle("Go")
for _, book := range results {
fmt.Printf(" %s – %s\\n", book.Title, book.Author)
}
// 按价格排序
fmt.Println("\\n按价格排序(从低到高):")
books := lib.GetBooksByPrice(true)
for _, book := range books {
fmt.Printf(" %s: ¥%.2f\\n", book.Title, book.Price)
}
// 统计信息
totalBooks, totalValue, topBorrowers := lib.GetStatistics()
fmt.Println("\\n统计信息:")
fmt.Printf("总藏书量: %d\\n", totalBooks)
fmt.Printf("总价值: ¥%.2f\\n", totalValue)
fmt.Printf("热门借阅者: %v\\n", topBorrowers)
}







