专业的编程技术博客社区

网站首页 > 博客文章 正文

Golang,反射,日志,XML读取与生成,JSON解析与生成,代码案例

baijin 2024-09-05 11:38:17 博客文章 4 ℃ 0 评论

反射

运行时反射

reflect包提供了运行时反射,程序在运行过程中动态操作结构体,当变量存储结构体属性名称,想要对结构体这个属性赋值或查看时,就可以使用反射。

反射还可以用做判断变量类型,整个reflect包中重要的2个类型:reflect.Type 类型和reflect.Value值,获取到Type和Value的函数,reflect.TypeOf(interface{}) 返回Type,reflect.ValueOf(interface{}) 返回值Value。

案例

package main

import (
	"fmt"
	"reflect"
)

func main() {
	// 反射
	a := 1.5
	t := reflect.TypeOf(a)
	v := reflect.ValueOf(a)
	fmt.Println(t)
	fmt.Println(v)
	a2 := People51{"张三", 67}
	t2 := reflect.TypeOf(a2)
	v2 := reflect.ValueOf(a2)
	fmt.Println(t2)
	fmt.Println(v2)
	// 字段个数
	fmt.Println("字段个数:", t2.NumField())
	fmt.Println("字段个数:", v2.NumField())
	// 根据下标获取
	fmt.Println("获取第0个属性名:", t2.Field(0).Name)
	fmt.Println("获取第0个属性值:", v2.Field(0).String())
	fmt.Println("获取第1个属性名:", t2.Field(1).Name)
	fmt.Println("获取第1个属性值:", v2.Field(1).Int())
	// 获取
	demo51_1()
	// 设置结构体属性的值是要传递结构体指针,否则无法获取设置的结构体对象
	demo51_2()

}

func demo51_2() {
	a4 := People51_2{"张三", 67}
	v4 := reflect.ValueOf(&a4).Elem()
	nameValue4 := v4.FieldByName("Name")
	ageValue42 := v4.FieldByName("Age")
	fmt.Println("能否访问:", nameValue4.CanSet())
	nameValue4.SetString("李四")
	ageValue42.SetInt(32)
	fmt.Println(a4) // {李四 32}
}

func demo51_1() {
	a3 := People51_2{"张三", 67}
	t3 := reflect.TypeOf(a3)
	v3 := reflect.ValueOf(a3)
	// 根据名称获取
	nameType3, ok3 := t3.FieldByName("Name")
	nameValue3 := v3.FieldByName("Name")
	fmt.Println("name字段:", nameType3, ok3)
	fmt.Println("name标签:", nameType3.Tag)
	fmt.Println("name标签:", nameType3.Tag.Get("name"))
	fmt.Println("name类型:", nameValue3.Kind().String())
	fmt.Println("name值:", nameValue3)
	ageType32, ok32 := t3.FieldByName("Age")
	ageValue32 := v3.FieldByName("Age")
	fmt.Println("age字段:", ageType32, ok32)
	fmt.Println("age类型:", ageValue32.Kind().String())
	fmt.Println("age值:", ageValue32)
}

type People51_2 struct {
	Name string `name:"json"`
	Age  int
}

type People51 struct {
	name string
	age  int
}

日志

log包

Go语言准备的log提供了对日志的支持,控制台打印的信息就是日志信息。有三种级别的日志输出:Print() 输出日志信息,Panic() 打印日志信息,并触发panic,日志信息为Panic信息;Fatal() 打印日志信息并调用: os.Exit(0)。所有日志信息打印时都还有时间,且颜色为红色,每种级别日志打印都提供了三个函数:Println(),Print(),Printf()。

案例

package main

import (
	"fmt"
	"log"
	"os"
)

func main() {
	// 日志
	log.Println("输出日志信息") // 2022/12/15 16:04:18 输出日志信息
	// log.Panicln("输出panic日志信息")
	// log.Fatalln("输出fatal日志信息")

	// 打印到文件
	f, _ := os.OpenFile("d://Temp/go.log", os.O_APPEND|os.O_CREATE, 0660)
	defer f.Close()
	logger := log.New(f, "[info] ", log.Ltime)
	logger.Println("输出日志信息=>文件")
	fmt.Println("main end")
}

xml读取与生成

XML

英文全称:Extendsible Markup Language,可扩展标记语言,encoding/xml报文提供了对XML序列化和反序列化的API,使用Unmarshal可以直接把XML字节切片数据转换为结果报文,转换时按照特定的规则进行转换,且数据类型可以自动转换。

案例

package main

import (
	"encoding/xml"
	"fmt"
	"os"
)

func main() {
	// xml读取
	p1 := new(People50)
	// 相对于项目的路径
	s1 := "demo01.xml"
	bytes1, _ := os.ReadFile(s1)
	xml.Unmarshal(bytes1, p1)
	fmt.Println(p1)

	p2 := new(Peoples50)
	s2 := "demo02.xml"
	bytes2, _ := os.ReadFile(s2)
	xml.Unmarshal(bytes2, p2)
	fmt.Println(p2)
}

type Peoples50 struct {
	XMLName xml.Name `xml:"peoples"`
	Version string   `xml:"version,attr"`
	// 首字母大写
	Peoples []People50 `xml:"people"`
}

type People50 struct {
	XMLName xml.Name `xml:"people"`
	Id      int      `xml:"id,attr"`
	Name    string   `xml:"name"`
	Address string   `xml:"address"`
	Age     int      `xml:"age"`
}
<?xml version="1.0" encoding="UTF-8" ?>

<people id="606">
    <name>刘甲</name>
    <address>北京</address>
    <age>19</age>
</people>
<?xml version="1.0" encoding="UTF-8" ?>

<peoples version="2.0">
    <people id="606">
        <name>刘甲</name>
        <address>北京</address>
        <age>19</age>
    </people>
    <people id="706">
        <name>安乙</name>
        <address>太原</address>
        <age>5</age>
    </people>
</peoples>

案例2

package main

import (
	"encoding/xml"
	"os"
)

const (
	Header = `<?xml version="1.0" encoding="UTF-8" ?>` + "\n"
)

func main() {
	// xml生成
	// xml/encoding下的Marshal函数
	p1 := People49{Id: 1, Name: "刘甲", Address: "北京", Age: 19}
	// 相对于项目的路径
	// bytes1, _ := xml.Marshal(p1)
	bytes1, _ := xml.MarshalIndent(p1, "", "    ")
	bytes1 = append([]byte(Header), bytes1...)
	s1 := "d:/Temp/case49.xml"
	os.WriteFile(s1, bytes1, 0660)

	// 输出第2个
	ps2 := Peoples49{Version: "3.0"}
	p2 := People49{Id: 2, Name: "安乙", Address: "北京", Age: 5}
	parr2 := []People49{p1, p2}
	ps2.Peoples = parr2
	bytes2, _ := xml.MarshalIndent(ps2, "", "    ")
	bytes2 = append([]byte(Header), bytes2...)
	s2 := "d:/Temp/demo02.xml"
	os.WriteFile(s2, bytes2, 0660)
}

type Peoples49 struct {
	XMLName xml.Name `xml:"peoples"`
	Version string   `xml:"version,attr"`
	// 首字母大写
	Peoples []People49 `xml:"people"`
}

type People49 struct {
	XMLName xml.Name `xml:"people"`
	Id      int      `xml:"id,attr"`
	Name    string   `xml:"name"`
	Address string   `xml:"address"`
	Age     int      `xml:"age"`
}

JSON

案例

package main

import (
	"encoding/json"
	"fmt"
)

func main() {
	// JSON
	p1 := People29{1, "张三", "北京", 1.34}
	b1, _ := json.Marshal(p1)
	fmt.Println(string(b1))
	// {"id":1,"name":"张三","Address":"北京"}
	p2 := new(People29)
	json.Unmarshal(b1, p2)
	fmt.Println(p2)
	//
	s3 := `{"id":1,"name":"张三","Address":"北京"}`
	b3 := []byte(s3)
	p3 := new(People29)
	json.Unmarshal(b3, p3)
	fmt.Println(p3)
}

// 要求属性名大写
type People29 struct {
	Id      int     `json:"id"`
	Name    string  `json:"name,omitempty"` // 没有name属性值,将会被忽略
	Address string  `json:",omitempty"`     // 名字和属性名相同
	Weight  float64 `json:"-"`              // JSON忽略
}

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表