欢迎光临
我们一直在努力

第五章:数组、切片与映射

第五章:数组、切片与映射

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, j1 {
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)
}

赞(0)
未经允许不得转载:171主机测评 » 第五章:数组、切片与映射
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址