Go语言练习——语法实践
目录
一、数组
1.多维数组的声明和使用
2.数组与切片的转换
3.数组在函数中的使用
二、切片
1.切片的动态扩容机制
2.切片的复制与修改
3.切片在排序算法中的应用
三、结构体
1.结构体的嵌套与方法
2.结构体与JSON的序列化
3.结构体的工厂模式
四、映射
1.映射的并发访问
2.映射与结构体的结合使用
3.映射在缓存中的应用
五、通道
1.通道的同步发送与接收
2.通道在数据传递中的应用
3.通道在并发控制中的应用
请继续努力
如果你努力了但是没有多大的改观
并不能证明你没有用而是代表你在赎罪
这个时候你应该更加努力
欠的账总会还完,日子总会阳光明媚的
努力刚开始很简单,但是到最后却很难
没有坚持的努力,实质上没有太大的意义
所以很多人看似输掉的是结果
本质上输掉的是过程
还是那句话:
人生没有白走的路,也没有白读的书
好运呢,只是你努力的伏笔而已
哪怕乌云密布,向上爬就是晴空万里
所以 请继续努力
—— 24.9.12、
一、数组
固定长度的数据集合
1.多维数组的声明和使用
package main
import "fmt"
func main() {
var arr [5][5]int
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
arr[i][j] = i * j
}
}
for i := range arr {
fmt.Println(arr[i])
}
for _, row := range arr {
for _, col := range row {
fmt.Printf("%d ", col)
}
fmt.Println()
}
}
2.数组与切片的转换
package main
import "fmt"
func main() {
arr := [5]int{1, 2, 3, 4, 5}
// 左闭右开
slice := arr[1:3]
fmt.Println("切片", slice)
slice2 := arr[0:4]
fmt.Println("切片2添加前:", slice2)
// append函数
slice2 = append(slice2, 6)
fmt.Println("切片2添加后:", slice2)
slice[1] = 100
fmt.Println("修改切片后的数组:", arr)
for i := range slice2 {
print(i, " ")
}
}
3.数组在函数中的使用
package main
import "fmt"
func sumArray(arr [5]int) int {
sum := 0
for _, value := range arr {
sum += value
}
return sum
}
func main() {
arr := [5]int{1, 2, 3, 4, 5}
result := sumArray(arr)
fmt.Println(result)
}
二、切片
动态长度的数据集合
1.切片的动态扩容机制
package main
import "fmt"
func main() {
// 初始化容量为5的切片
slice := make([]int, 0, 5)
for i := 0; i < 10; i++ {
slice = append(slice, i)
}
fmt.Println("扩容后的切片为:", slice)
}
2.切片的复制与修改
package main
import "fmt"
func main() {
original := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
copySilice := make([]int, len(original))
copy(copySilice, original)
copySilice[0] = 1
copySilice[1] = 2
copySilice[3] = 4
fmt.Println("原始切片为:", original)
fmt.Println("复制后的切片为:", copySilice)
}
3.切片在排序算法中的应用
package main
import (
"fmt"
"sort"
)
func main() {
slice := []int{9, 11, 7, 17, 25, 43, 3, 27, 18}
sort.Ints(slice)
fmt.Println("排序后的切片为:", slice)
}
三、结构体
自定义数据据类型
1.结构体的嵌套与方法
package main
import "fmt"
type Address struct {
City, Street string
}
type Person struct {
Name string
Age int
// 结构体的嵌套
Address Address
}
// 打招呼
func (p *Person) Greet() {
fmt.Printf("Hello,My name is %s,I am %d old and I live in %s\n", p.Name, p.Age, p.Address.City)
}
func main() {
person := Person{
Name: "lcl",
Age: 23,
Address: Address{"西宁市", "同仁路"},
}
person.Greet()
}
2.结构体与JSON的序列化
package main
import (
"encoding/json"
"fmt"
)
type Person1 struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
person := Person1{Name: "Alice", Age: 30}
jsonData, err := json.Marshal(person)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Println("JSONdata:", string(jsonData))
}
3.结构体的工厂模式
工厂模式 —— 设计模式的一种
package main
import "fmt"
type People struct {
Name string
Age int
}
func NewPeople(name string, age int) *People {
return &People{name, age}
}
func main() {
people := NewPeople("John", 18)
fmt.Printf("new person:%+v\n", people)
}
四、映射
键值对集合
1.映射的并发访问
package main
import (
"fmt"
"sync"
)
// 映射的并发访问
func main() {
var m sync.Map
m.Store("key1", "value1")
m.Store("key2", "value2")
// Load
if v, ok := m.Load("key1"); ok {
fmt.Println("key1:", v)
}
// Range
m.Range(func(key, value interface{}) bool {
fmt.Print(key, ":", value, "\n")
return true
})
}
2.映射与结构体的结合使用
package main
import "fmt"
type Book struct {
title string
author string
}
func main() {
books := make(map[string]Book)
books["1"] = Book{"Go Programming", "Jane Doe"}
books["2"] = Book{"Learn Go", "Jane Doe"}
for key, value := range books {
fmt.Println("Book ID:", key, " Title:", value.title, " Author:", value.author)
}
}
3.映射在缓存中的应用
package main
import "fmt"
func fibonacci(n int) int {
cache := make(map[int]int)
return fib(n, cache)
}
func fib(n int, cache map[int]int) int {
if n <= 1 {
return n
}
if val, ok := cache[n]; ok {
return val
}
cache[n] = fib(n-1, cache) + fib(n-2, cache)
return cache[n]
}
func main() {
// 斐波那契数列的第n项
fmt.Println(fib(5, make(map[int]int)))
}
五、通道
并发编程的同步机制
1.通道的同步发送与接收
package main
import "fmt"
// 当接收到通道中的值时,它表示工作完成。
func worker(done chan bool) {
fmt.Println("Worker started") // 打印开始工作的信息
<-done // 阻塞等待,直到从通道done接收到一个值
fmt.Println("Worker finished") // 当从通道接收到值时,打印完成工作的信息
}
func main() {
// 创建一个布尔类型的无缓冲通道
done := make(chan bool)
// 使用 go 关键字启动一个新的goroutine来执行worker函数
// 注意:原代码中的 goworker(done) 应该是 go worker(done)
go worker(done)
fmt.Println("Main waiting")
// 主goroutine向通道done发送一个值,通知worker函数可以结束
done <- true
}
2.通道在数据传递中的应用
package main
import "fmt"
func sendData(ch chan int) {
for i := 0; i < 5; i++ {
ch <- i
}
close(ch)
}
func main() {
ch := make(chan int)
go sendData(ch)
for data := range ch {
fmt.Println("Received", data)
}
}
3.通道在并发控制中的应用
package main
import (
"fmt"
"sync"
)
func main() {
// 缓冲通道,容量为2
var wg sync.WaitGroup
// 缓冲通道,容量为2
ch := make(chan struct{}, 2)
wg.Add(2)
for i := 0; i < 2; i++ {
go func(id int) {
defer wg.Done()
// 进入
ch <- struct{}{}
fmt.Printf("Goroutine %d is processing\n", id)
// 离开
<-ch
}(i)
}
wg.Wait()
fmt.Println("All goroutines have finished")
}