生成xml
package main
import (
"encoding/xml"
"fmt"
"os"
)
// 定义结构体
type A struct {
XMLName xml.Name `xml:"a"`
Id int `xml:"id,attr"`
Name string `xml:"name"`
Age int `xml:"age"`
}
func main() {
//结构体赋值
a := A{Id: 123, Name: "张三", Age: 456}
//对内容进行格式化
b, _ := xml.MarshalIndent(a, "", " ")
//追加xml头
b = append([]byte(xml.Header), b...)
//写入到磁盘中
os.WriteFile("d://aa.xml", b, 0666)
fmt.Println("写入成功")
}
读取xml的内容
package main
import (
"encoding/xml"
"fmt"
"os"
)
//<?xml version="1.0" encoding="UTF-8"?>
//<a id="123">
//<name>张三</name>
//<age>456</age>
//</a>
// 定义结构体
type A struct {
XMLName xml.Name `xm:"a"`
Id int `xml:"id,attr"`
Name string `xml:"name"`
Age int `xml:"age"`
}
func main() {
//创建指针类型的结构体
a := new(A)
b, _ := os.ReadFile("d://aa.xml")
//把xml字节切片数据转换为结构体
xml.Unmarshal(b, a)
//读取xml的内容
//&{{ a} 123 张三 456}
fmt.Println(a)
}
读取多层级的xml内容
xml内容
<?xml version="1.0" encoding="UTF-8"?>
<xue version="1">
<a id="123">
<name>张三</name>
<age>11</age>
</a>
<a id="456">
<name>李四</name>
<age>22</age>
</a>
</xue>
代码
package main
import (
"encoding/xml"
"fmt"
"os"
)
// 定义结构体
type Xue struct {
XMLName xml.Name `xml:"xue"`
Version int `xml:"version,attr"`
//属性必须是大写开头
A []A `xml:"a"`
}
// 定义结构体
type A struct {
XMLName xml.Name `xml:"a"`
Id int `xml:"id,attr"`
Name string `xml:"name"`
Age int `xml:"age"`
}
func main() {
//创建指针类型的结构体
xue := new(Xue)
b, _ := os.ReadFile("d://aa.xml")
//把xml字节切片的数据转换成结构体
xml.Unmarshal(b, xue)
//读取xml的内容
//&{{ xue} 1 [{{ a} 123 张三 11} {{ a} 456 李四 22}]}
fmt.Println(xue)
}
像id="123" ,version="1" 这样的格式 在定义结构体的标记的时候,必须加attr
打印日志
package main
import (
"log"
"os"
)
func main() {
//打开文件
f, _ := os.OpenFile("d://aa.log", os.O_APPEND|os.O_CREATE, 0777)
//写入日志到文件中
logger := log.New(f, "[前缀]", log.Ltime)
logger.Println("打印普通日志到文件")
log.Println("打印普通日志到控制台")
log.Panic("打印错误日志")
log.Fatal("打印退出日志")
}
线程休眠和计时器
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println("你好啊")
time.AfterFunc(3e9, func() {
fmt.Println("3秒后触发定时任务")
})
//延迟4秒才往下执行代码
time.Sleep(4e9)
fmt.Println("结束了")
}
goroutine协程/线程
package main
import (
"fmt"
"time"
)
func aa(k int) {
for i := 0; i < 50; i++ {
fmt.Println(i, "==", k)
}
}
func main() {
for i := 0; i < 5; i++ {
//开启协程/线程 异步
go aa(i)
}
//使用停顿时间 3秒
time.Sleep(3e9)
}
waitgroup阻塞计数器
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
//计数器设置为5
wg.Add(5)
for i := 0; i < 5; i++ {
go func() {
fmt.Println(i)
//计数器减去1
wg.Done()
}()
}
//阻塞线程 当计数器为0的时候 才放行
wg.Wait()
fmt.Println("程序结束")
}
互斥锁
在多线程竞争资源的时候,会造成死锁
使用互斥锁可以避免死锁,在操作之前先加锁,然后操作完成后解锁
别的线程才能访问这块的资源
package main
import (
"fmt"
"sync"
)
var (
//全局变量
num = 100
//计数器
wg sync.WaitGroup
//互斥锁
lock sync.Mutex
)
func main() {
//开启10个计数器
wg.Add(10)
for i := 0; i < 10; i++ {
//线程异步
go func() {
//加锁
lock.Lock()
for j := 0; j < 10; j++ {
fmt.Println(i, "=========", j)
}
//解锁
lock.Unlock()
//计数器减去1
wg.Done()
}()
}
//阻塞线程
wg.Wait()
fmt.Println("程序结束")
}
读写锁
读写锁就是线程可以一个写 多个线程读操作
package main
import (
"fmt"
"sync"
)
var (
//全局变量
num = 100
//计数器
wg sync.WaitGroup
//读写锁
rw sync.RWMutex
)
func main() {
//创建一个map
m := make(map[int]int)
wg.Add(10)
for i := 0; i < 10; i++ {
go func(j int) {
//写入map数据 加锁
rw.Lock()
m[j] = j
//写完之后 释放锁
fmt.Println("map中的数据:", m)
rw.Unlock()
wg.Done()
}(i) //把i 传进方法中
}
wg.Wait()
fmt.Println("程序结束")
}