Go语言基础Json序列化反序列化及文件读写示例详解

目录
  • 概述
  • JSON序列化
    • 结构体转JSON
    • map转JSON
    • 切片转JSON
  • JSON反序列化
    • JSON转map
    • JSON转结构体
    • JSON转切片
  • 写JSON文件
    • map写入JSON文件
    • 切片写入JSON文件
    • 结构体写入JSON文件
  • 读JSON文件
    • 解码JSON文件为map
    • 解码JSON文件为切片
    • 解码JSON文件为结构体
  • 示例

概述

JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的、键值对的数据交换格式。结构由大括号'{}',中括号'[]',逗号',',冒号';',双引号'""'组成,包含的数据类型有Object,Number,Boolean,String,Array, NULL等。

JSON序列化

将Go语言原数据转换成JSON格式字符串

语法:

//传map,结构体,slice...,返回结果byte切片和error是否错误
func Marshal(v interface{}) ([]byte, error)

结构体转JSON

type Person struct{
   Name string   //姓名
   Age int       //年龄
   Sex rune      //性别
   Hobby []string  //爱好
   Money float64   //钱
}
person:=Person{Name:"张三",Age:18,Sex:'男',Hobby:[]string{"听音乐","看书","打篮球"},Money:18.62}
if bytes,err:=json.Marshal(person);err!=nil{
  fmt.Println("编码错误",err)
}else{
//{"Name":"张三","Age":18,"Sex":30007,"Hobby":["听音乐","看书","打篮球"],"Money":18.62}
  fmt.Println("编码成功:",string(bytes))
}

map转JSON

p:=make(map[string]interface{},0)
p["0"]=map[string]interface{}{"name":"张三","age":18,"sex":'男',"hobby":[]string{"听音乐","看书","打篮球"},"money":18.62}
p["1"]=map[string]interface{}{"name":"李四","age":19,"sex":'女',"hobby":[]string{"听音乐","看电影","打足球"},"money":1.62}

if bytes,err:=json.Marshal(p);err!=nil{
   fmt.Println("编码错误",err)
}else{
   fmt.Println(string(bytes))
}

切片转JSON

  p:=make([]map[string]interface{},0)
  p1:=map[string]interface{}{"name":"张三","age":18,"sex":'男',"hobby":[]string{"听音乐","看书","打篮球"},"money":18.62}
  p2:=map[string]interface{}{"name":"李四","age":19,"sex":'女',"hobby":[]string{"听音乐","看电影","打足球"},"money":1.62}
  p=append(p,p1,p2)

  if bytes,err:=json.Marshal(p);err!=nil{
    fmt.Println("编码错误",err)
  }else{
    fmt.Println(string(bytes))
  }

JSON反序列化

将JSON格式字符串转换成Go语言原数据

//传入JSON字符串的byte字节和Go接收数据的类型指针,返回err错误,是否返回成功
func Unmarshal(data []byte, v interface{}) error

JSON转map

str:=`{"Name":"张三","Age":18,"Sex":30007,"Hobby":["听音乐","看书","打篮球"],"Money":18.62}`
p:=make(map[string]interface{}, 0)
if err:=json.Unmarshal([]byte(str),&p);err!=nil{
  fmt.Println("解码失败",err)
}else{
  fmt.Println("解析成功",p)
}

JSON转结构体

str:=`{"Name":"张三","Age":18,"Sex":30007,"Hobby":["听音乐","看书","打篮球"],"Money":18.62}`
var p Person
if err:=json.Unmarshal([]byte(str),&p);err!=nil{
  fmt.Println("解码失败",err)
}else{
  fmt.Println("解析成功",p)
}

JSON转切片

str:=`[{"Hobby":["听音乐","看书","打篮球"]}]`
p:=make([]map[string]interface{}, 0)

if err:=json.Unmarshal([]byte(str),&p);err!=nil{
  fmt.Println("解码失败",err)
}else{
  fmt.Println("解析成功",p)
}

写JSON文件

将Go语言源数据写入到json文件

//第一步  传文件的路径,返回文件的可读可写,error:是否成功
//flag:文件标识:是创建还是,追加......
//parm:文件模式表示文件的模式和权限位,通常,请求的模式为 0666,它使该文件可由任何人读和写
func OpenFile(name string, flag int, perm FileMode) (*File, error)
或者
func Create(name string) (*File, error)  //传入文件的名字,返回文件的对象和error是否成功
//第二步 传文件对象,返回一个从w读取的新编码器
func NewEncoder(w io.Writer) *Encoder
//第三步 编码器将v写入流中,后换行
func (enc *Encoder) Encode(v interface{}) error

map写入JSON文件

p:=make(map[string]interface{}, 0)
p["name"]="张三"
p["age"]=18
p["sex"]='男'
p["hobby"]=[]string{"听英语","看书"}
p["money"]=15.63
if distFile,err:=os.OpenFile("map.json",os.O_CREATE,0666);err!=nil{
  fmt.Println("创建文件失败",err)
}else {
  enc:=json.NewEncoder(distFile)
  if err:=enc.Encode(p);err!=nil {
    fmt.Println("写入文件失败", err)
  }else{
    fmt.Println("写入文件成功")
  }
}

切片写入JSON文件

p:=make([]map[string]interface{}, 0)
p1:=map[string]interface{}{"name":"张三","age":18,"sex":'男',"hobby":[]string{"听书","看电视"},"money":15.84}
p2:=map[string]interface{}{"name":"李四","age":20,"sex":'女',"hobby":[]string{"打篮球","看书"},"money":125.84}
p=append(p,p1,p2)
if distFile,err:=os.OpenFile("slice.json",os.O_CREATE,0666);err!=nil{
  fmt.Println("创建slice文件失败", err)
}else {
  enc:=json.NewEncoder(distFile)
  if err:=enc.Encode(p);err!=nil{
    fmt.Println("写入slice 文件失败", err)
  }else{
    fmt.Println("写入slice 文件成功")
  }
}

结构体写入JSON文件

p:=Person{Name:"张三",Age:18,Sex:'男',Hobby:[]string{"听英语","读书"},Money:15.35}
if distFile,err:=os.OpenFile("张三.json",os.O_CREATE|os.O_APPEND,0666);err!=nil{
  fmt.Println("创建文件失败",err)
}else{
  enc:=json.NewEncoder(distFile)
  if err:=enc.Encode(&p);err!=nil {
    fmt.Println("写入文件失败",err)
  }else {
    fmt.Println("写入文件成功")
  }
}

读JSON文件

将json文件转换成Go语言源数据

//第一步  传文件的路径,返回文件的可读可写,error:是否成功
func Open(name string) (*File, error)
//第二步 传文件对象,返回一个从r读取的新解码器
func NewDecoder(r io.Reader) *Decoder
//第三步 解码器将值存储在v值中
func (dec *Decoder) Decode(v interface{}) error

解码JSON文件为map

p:=make(map[string]interface{}, 0)
if srcFile,err:=os.Open("map.json");err!=nil{
  fmt.Println("打开map 文件失败",err)
}else{
  en:=json.NewDecoder(srcFile)
  if err:=en.Decode(&p);err!=nil{
    fmt.Println("读入map 文件失败",err)
  }else {
    fmt.Println("读取map 文件成功",p)
  }
}

解码JSON文件为切片

p:=make([]map[string]interface{}, 0)
if srcFile,err:=os.Open("slice.json");err!=nil{
  fmt.Println("打开slice 文件失败", err)
}else{
  en:=json.NewDecoder(srcFile)
  if err:=en.Decode(&p);err!=nil{
    fmt.Println("读入slice 文件失败", err)
  }else {
    fmt.Println("读取slice 文件成功", p)
  }
}

解码JSON文件为结构体

var p =new(Person)
if srcFile,err:=os.Open("struct.json");err!=nil{
  fmt.Println("打开struct 文件失败", err)
}else{
  en:=json.NewDecoder(srcFile)
  if err:=en.Decode(&p);err!=nil{
    fmt.Println("读入struct 文件失败", err)
  }else{
    fmt.Println("读取struct 文件成功", *p)
  }
}

示例

package main
import (
	"encoding/json"
	"fmt"
	"os"
)
type Person struct {
	Name  string   //姓名
	Age   int      //年龄
	Sex   rune     //性别
	Hobby []string //爱好
	Money float64  //钱
}
func main() {
	fmt.Println("---------------JSON序列化----------")
	//JSON序列化
	//结构体
	marshalStrut()
	//map
	marshalMap()
	//slice
	marshalSlice()
	fmt.Println("\n", "---------------JSON反序列化----------", "\n")
	//JSON反序列化
	//map
	unmarshalMap()
	//struct
	unmarshalStruct()
	//slice
	unmarshalSlice()
	fmt.Println("\n", "---------------写JSON文件----------", "\n")
	//结构体
	writeStructFile()
	//map
	writeMapFile()
	//slice
	writeSliceFile()
	fmt.Println("\n", "---------------读JSON文件----------", "\n")
	//struct
	readStructFile()
	//map
	readMapFile()
	//slice
	readSliceFile()
}
/************************序列化*********************/
func marshalStrut() {
	person := Person{Name: "张三", Age: 18, Sex: '男', Hobby: []string{"听音乐", "看书", "打篮球"}, Money: 18.62}
	if bytes, err := json.Marshal(person); err != nil {
		fmt.Println("结构体序列化错误", err)
	} else {
		//{"Name":"张三","Age":18,"Sex":30007,"Hobby":["听音乐","看书","打篮球"],"Money":18.62}
		fmt.Println("结构体序列化成功:", string(bytes))
	}
}
func marshalMap() {
	p := make(map[string]interface{}, 0)
	p["0"] = map[string]interface{}{"name": "张三", "age": 18, "sex": '男', "hobby": []string{"听音乐", "看书", "打篮球"}, "money": 18.62}
	p["1"] = map[string]interface{}{"name": "李四", "age": 19, "sex": '女', "hobby": []string{"听音乐", "看电影", "打足球"}, "money": 1.62}

	if bytes, err := json.Marshal(p); err != nil {
		fmt.Println("map 序列化错误", err)
	} else {
		// {"0":{"age":18,"hobby":["听音乐","看书","打篮球"],"money":18.62,"name":"张三","sex":30007},"1":{"age":19,"hobby":["听音乐","看电影","打足球"],"money":1.62,"name":"李四","sex":22899}}
		fmt.Println("map 序列化成功", string(bytes))
	}
}
func marshalSlice() {
	p := make([]map[string]interface{}, 0)
	p1 := map[string]interface{}{"name": "张三", "age": 18, "sex": '男', "hobby": []string{"听音乐", "看书", "打篮球"}, "money": 18.62}
	p2 := map[string]interface{}{"name": "李四", "age": 19, "sex": '女', "hobby": []string{"听音乐", "看电影", "打足球"}, "money": 1.62}
	p = append(p, p1, p2)
	if bytes, err := json.Marshal(p); err != nil {
		fmt.Println("slice 序列化错误", err)
	} else {
		// [{"age":18,"hobby":["听音乐","看书","打篮球"],"money":18.62,"name":"张三","sex":30007},{"age":19,"hobby":["听音乐","看电影","打足球"],"money":1.62,"name":"李四","sex":22899}]
		fmt.Println("slice 序列化成功", string(bytes))
	}
}
/************************反序列化*********************/
func unmarshalMap() {
	str := `{"Name":"张三","Age":18,"Sex":30007,"Hobby":["听音乐","看书","打篮球"],"Money":18.62}`
	p := make(map[string]interface{}, 0)
	if err := json.Unmarshal([]byte(str), &p); err != nil {
		fmt.Println("map 反序列化失败", err)
	} else {
		//map[Age:18 Hobby:[听音乐 看书 打篮球] Money:18.62 Name:张三 Sex:30007]
		fmt.Println("map 反序列化成功", p)
	}
}
func unmarshalStruct() {
	str := `{"Name":"张三","Age":18,"Sex":30007,"Hobby":["听音乐","看书","打篮球"],"Money":18.62}`
	var p Person
	if err := json.Unmarshal([]byte(str), &p); err != nil {
		fmt.Println("struct 反序列化失败", err)
	} else {
		//{张三 18 30007 [听音乐 看书 打篮球] 18.62}
		fmt.Println("struct 反序列化成功", p)
	}
}
func unmarshalSlice() {
	str := `[{"Hobby":["听音乐","看书","打篮球"]},{"Hobby":["听书","看书","打足球"]}]`
	p := make([]map[string]interface{}, 0)

	if err := json.Unmarshal([]byte(str), &p); err != nil {
		fmt.Println("slice 反序列化失败", err)
	} else {
		// [map[Hobby:[听音乐 看书 打篮球]]]
		fmt.Println("slice 反序列化成功", p)
	}
}
/************************写JSON文件*********************/
func writeStructFile() {
	p := Person{Name: "张三", Age: 18, Sex: '男', Hobby: []string{"听英语", "读书"}, Money: 15.35}
	if distFile, err := os.OpenFile("struct.json", os.O_CREATE|os.O_TRUNC, 0666); err != nil {
		fmt.Println("创建struct文件失败", err)
	} else {
		enc := json.NewEncoder(distFile)
		if err := enc.Encode(&p); err != nil {
			fmt.Println("写入struct文件失败", err)
		} else {
			fmt.Println("写入struct文件成功")
		}
	}
}
func writeMapFile() {
	p := make(map[string]interface{}, 0)
	p["name"] = "张三"
	p["age"] = 18
	p["sex"] = '男'
	p["hobby"] = []string{"听英语", "看书"}
	p["money"] = 15.63
	if distFile, err := os.OpenFile("map.json", os.O_CREATE, 0666); err != nil {
		fmt.Println("创建map 文件失败", err)
	} else {
		enc := json.NewEncoder(distFile)
		if err := enc.Encode(p); err != nil {
			fmt.Println("写入map文件失败", err)
		} else {
			fmt.Println("写入map 文件成功")
		}
	}
}
func writeSliceFile() {
	p := make([]map[string]interface{}, 0)
	p1 := map[string]interface{}{"name": "张三", "age": 18, "sex": '男', "hobby": []string{"听书", "看电视"}, "money": 15.84}
	p2 := map[string]interface{}{"name": "李四", "age": 20, "sex": '女', "hobby": []string{"打篮球", "看书"}, "money": 125.84}
	p = append(p, p1, p2)
	if distFile, err := os.OpenFile("slice.json", os.O_CREATE, 0666); err != nil {
		fmt.Println("创建slice文件失败", err)
	} else {
		enc := json.NewEncoder(distFile)
		if err := enc.Encode(p); err != nil {
			fmt.Println("写入slice 文件失败", err)
		} else {
			fmt.Println("写入slice 文件成功")
		}
	}
}
/************************读JSON文件*********************/
func readStructFile() {
	var p = new(Person)

	if err := readFile("struct.json", "打开struct 文件失败", &p); err != nil {
		fmt.Println("读入struct 文件失败", err)
	} else {
		fmt.Println("读取struct 文件成功", *p)
	}

}
func readMapFile() {
	p := make(map[string]interface{}, 0)

	if err := readFile("map.json", "打开map 文件失败", &p); err != nil {
		fmt.Println("读取map 文件失败", err)
	} else {
		fmt.Println("读取map 文件成功", p)
	}
}
func readSliceFile() {
	p := make([]map[string]interface{}, 0)
	if err := readFile("slice.json", "打开slice 文件失败", &p); err != nil {
		fmt.Println("读入slice 文件失败", err)
	} else {
		fmt.Println("读取slice 文件成功", p)
	}
}
//封装
func readFile(f string, c string, v interface{}) error {
	if srcFile := openFile(f, c); srcFile != nil {
		en := json.NewDecoder(srcFile)
		if err := en.Decode(v); err != nil {
			return err
		}
	}
	return nil
}
func openFile(f string, c string) *os.File {
	if srcFile, err := os.Open(f); err != nil {
		fmt.Println(c, err)
	} else {
		return srcFile
	}
	return nil
}

以上就是Go语言基础Json序列化反序列化及文件读写示例详解的详细内容,更多关于Go语言Json序列化反序列化及文件读写的资料请关注我们其它相关文章!

(0)

相关推荐

  • 图文详解go语言反射实现原理

    Go反射的实现和 interface 和 unsafe.Pointer 密切相关.如果对golang的 interface 底层实现还没有理解,可以去看我之前的文章: Go语言interface底层实现 , unsafe.Pointer 会在后续的文章中做介绍. (本文目前使用的Go环境是Go 1.12.9) interface回顾 首先我们简单的回顾一下interface的结构,总体上是: 细分下来分为有函数的 iface 和无函数的 eface (就是 interface{} ); 无函数的

  • Go语言基础闭包的原理分析示例详解

    目录 一. 闭包概述 二. 代码演示 运行结果 代码说明 一. 闭包概述 闭包就是解决局部变量不能被外部访问的一种解决方案 闭包是把函数当作返回值的一种应用 二. 代码演示 总体思想为:在函数内部定义局部变量,把另一个函数当作返回值,局部变量对于返回值函数相当于全部变量,所以多次调用返回值函数局部变量的值跟随变化. // closure.go package main import ( "fmt" "strings" ) func main() { f := clo

  • Go语言学习笔记之反射用法详解

    本文实例讲述了Go学习笔记之反射用法.分享给大家供大家参考,具体如下: 一.类型(Type) 反射(reflect)让我们能在运行期探知对象的类型信息和内存结构,这从一定程度上弥(mi)补了静态语言在动态行为上的不足.同时,反射还是实现元编程的重要手段. 和 C 数据结构一样,Go 对象头部并没有类型指针,通过其自身是无法在运行期获知任何类型相关信息的.反射操作所需要的全部信息都源自接口变量.接口变量除存储自身类型外,还会保存实际对象的类型数据. func TypeOf(i interface{

  • Go语言基础反射示例详解

    目录 概述 语法 一.基本操作 二.修改目标对象 三.动态调用方法 总结 示例 概述 在程序运行期对程序动态的进行访问和修改 reflect godoc: https://golang.org/pkg/reflect/ reflect包有两个数据类型: Type:数据类型 [reflect.TypeOf():是获取Type的方法] Value:值的类型[reflect.ValueOf():是获取Value的方法] 语法 一.基本操作 获取变量类型 func TypeOf(i interface{

  • Go语言基础单元测试与性能测试示例详解

    目录 概述 单元测试 代码说明如下 问题 注意 性能测试 基本使用 自定义测试时间 概述 测试不是Go语言独有的,其实在很多语言都有测试,例如:Go.Java.Python- 要想成为一名合格的大牛,这是程序员必须具备的一项技能,特别是一些大公司,这是加分的一项,主要有如下优点: 代码可以随时测试,保证代码不会产生错误 写出更加高效的代码 testing文档 Testing_flags文档 单元测试 格式:func TestXXX(t *testing.T) //add.go package c

  • 谈谈Go语言的反射三定律

    简介 Reflection(反射)在计算机中表示 程序能够检查自身结构的能力,尤其是类型.它是元编程的一种形式,也是最容易让人迷惑的一部分. 虽然Go语言没有继承的概念,但为了便于理解,如果一个struct A 实现了 interface B的所有方法时,我们称之为"继承". 类型和接口 反射建立在类型系统之上,因此我们从类型基础知识说起. Go是静态类型语言.每个变量都有且只有一个静态类型,在编译时就已经确定.比如 int.float32.*MyType.[]byte. 如果我们做出

  • Go语言基础Json序列化反序列化及文件读写示例详解

    目录 概述 JSON序列化 结构体转JSON map转JSON 切片转JSON JSON反序列化 JSON转map JSON转结构体 JSON转切片 写JSON文件 map写入JSON文件 切片写入JSON文件 结构体写入JSON文件 读JSON文件 解码JSON文件为map 解码JSON文件为切片 解码JSON文件为结构体 示例 概述 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的.键值对的数据交换格式.结构由大括号'{}',中括

  • Go语言基础for循环语句的用法及示例详解

    目录 概述 语法 注意 示例一  死循环,读取文件 示例二  打印乘法表 示例三  遍历字符串,数组,map 概述 for循环是一个循环控制结构,可以执行指定次数的循环 语法 第一种 for {} //无线循环 第二种 for 条件语句{} 第三种 for 初始语句; 条件语句; 迭代后语句 {} 第四种 for key,value:=range 表达式/变量{} 注意 省略初始条件,相当于while循环体必须用 { } 括起来初始化语句和后置语句是可选的如果只剩下条件表达式了,那么那两个分号也

  • Go语言基础switch条件语句基本用法及示例详解

    目录 概述 语法 第一种[switch 带上表达式] 第二种[switch 不带表达式] 第三种[switch 初始化,表达式] 注意 示例一[根据今天的日期打印今天星期几] 示例二[根据分数打印A,B,C,D] 示例三[算数] 概述 传入条件的不同,会执行不同的语句 每一个case分支都是唯一的,从上到下逐一测试,直到匹配为止. 语法 第一种[switch 带上表达式] switch 表达式 { case 表达式1,表达式2, ... : 语句块1 case 表达式3, 表达式4, ... :

  • C语言函数基础教程分类自定义参数及调用示例详解

    目录 1.  函数是什么? 2.  C语言中函数的分类 2.1 库函数 2.1.1 为什么要有库函数 2.1.2 什么是库函数 2.1.3 主函数只能是main()吗 2.1.4常见的库函数 2.2 自定义函数 2.2.1自定义函数是什么 2.2.2为什么要有自定义函数 2.2.3函数的组成 2.2.4 举例展示 3. 函数的参数 3.1 实际参数(实参) 3.2  形式参数(形参) 4. 函数的调用 4.1 传值调用 4.2  传址调用 4.3 练习 4.3.1. 写一个函数判断一年是不是闰年

  • Go语言学习笔记之文件读写操作详解

    目录 文件写 文件读 小结 文件操作比较多,分为几篇来写吧.首先是文件的读写,在平时的工程化操作中使用最多. 文件写 样例代码如下 package main import ( "bufio" "fmt" "io" "os" ) //写文件 func DoWriteFile() error { _filePath := "./test.txt" _file, _err := os.OpenFile(_file

  • .NetCore实现上传多文件的示例详解

    本章和大家分享的是.NetCore的MVC框架上传文件的示例,主要讲的内容有:form方式提交上传,ajax上传,ajax提交+上传进度效果,Task并行处理+ajax提交+上传进度,相信当你读完文章内容后能后好的收获,如果可以不妨点个赞:由于昨天电脑没电了,快要写完的内容没有保存,今天早上提前来公司从头开始重新,断电这情况的确让人很头痛啊,不过为了社区的分享环境,这也是值得的,不多说了来进入今天的正篇环节吧: form方式上传一组图片 先来看看咋们html的代码,这里先简单说下要上传文件必须要

  • Pandas对CSV文件读写操作详解

    目录 什么是 CSV 文件 CSV 库解析 CSV 文件 读取 CSV 文件 CSV reader 参数 CSV 文件的写入 使用 pandas 库解析 CSV 文件 pandas 读取 CSV 文件 pandas 写入 CSV 文件 什么是 CSV 文件 CSV 文件(逗号分隔值文件)是一种纯文本文件,它使用特定的结构来排列表格数据.因为它是一个纯文本文件,所以只能包含实际的文本数据,换句话说就是可打印的 ASCII 或 Unicode 字符. 通常,CSV 文件的结构由其名称给出,使用逗号分

  • Go json自定义Unmarshal避免判断nil示例详解

    目录 前言 使用默认的 Unmarshal 方法 自定义的 Unmarshal 方法 前言 腾讯<Go安全指南>中提到[必须]nil指针判断:进行指针操作时,必须判断该指针是否为nil,防止程序panic,尤其在进行结构体Unmarshal时.但如果每次使用都要判断一下是否 nil 防止 panic的话,那么这样的代码就会比较麻烦,这里我们可以使用一个自定义的方法,来避免这种情况. 使用默认的 Unmarshal 方法 package main import ( "encoding/

  • Go语言学习教程之goroutine和通道的示例详解

    目录 goroutine 通道 Range 和 Close Select 官方留的两道练习题 等价的二叉树 网络爬虫 源码地址 goroutine goroutine是由Go运行时管理的轻量级线程. go f(x, y, z)在一个新的goroutine中开始执行f(x, y,z). goroutines运行在相同的地址空间中,所以对共享的内存访问必须同步.sync包提供了基本的同步原语(synchronization primitives),比如互斥锁(mutual exclusion loc

  • C语言嵌入式实现支持浮点输出的printf示例详解

    目录 简介 背景 C语言可变参数函数 踩坑 功能实现 简介 mr-printf 模块为 mr-library 项目下的可裁剪模块,以C语言编写,可快速移植到各种平台(主要以嵌入式mcu为主). mr-printf 模块用以替代 libc 中 printf, 可在较小资源占用的同时支持绝大部分 printf 功能,于此同时还支持对单独功能模块的裁剪以减少用户不需要功能的资源占用. 背景 printf 大家应该使用的比较多,但是在嵌入式平台中,尤其是单片机中,libc中的printf对内存的占用较高

随机推荐