在Go语言中,可以这样使用Json
在Go语言中,处理JSON数据通常涉及编码(将Go结构体转换为JSON字符串)和解码(将JSON字符串转换为Go结构体)。Go标准库中的
encoding/json
包提供了这些功能。第三方插件可以使用"github.com/goccy/go-json"也有同样的功能
Marshal
函数将会递归遍历整个对象,依次按成员类型对这个对象进行编码,类型转换规则如下:
-
bool
类型 转换为JSON
的Boolean
-
整数,浮点数等数值类型 转换为
JSON
的Number
-
string
转换为JSON
的字符串(带""引号) -
struct
转换为JSON
的Object
,再根据各个成员的类型递归打包 -
数组或切片 转换为
JSON
的Array
-
[]byte
会先进行base64
编码然后转换为JSON
字符串 -
map
转换为JSON
的Object
,key
必须是string
-
interface{}
按照内部的实际类型进行转换 -
nil
转为JSON
的null
-
channel
,func
等类型 会返回UnsupportedTypeError
1、使用标准库中的encoding/json
包
字符串输出&格式化输出&解码
package mainimport ("encoding/json""fmt"
)type ColorGroup struct {ID intName stringColors []string
}// 创建一个ColorGroup类型的变量来保存解码后的数据
var decodedGroup ColorGroupfunc main() {group := ColorGroup{ID: 1,Name: "Reds",Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},}// 将结构体编码为JSON字符串jsonData1, err := json.Marshal(group)jsonData2, err := json.MarshalIndent(group, "", " ")if err != nil {fmt.Println("error:", err)return}// 打印JSON字符串fmt.Println(string(jsonData1))fmt.Println(string(jsonData2))// Output://{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}// {// "ID": 1,// "Name": "Reds",// "Colors": [// "Crimson",// "Red",// "Ruby",// "Maroon"// ]// }// 将JSON字符串解码到ColorGroup结构体中err = json.Unmarshal([]byte(jsonData1), &decodedGroup)if err != nil {fmt.Println("error:", err)return}// 打印解码后的数据fmt.Printf("ID: %d, Name: %s, Colors: %v\n", decodedGroup.ID, decodedGroup.Name, decodedGroup.Colors)// Output: ID: 1, Name: Reds, Colors: [Crimson Red Ruby Maroon]fmt.Println(decodedGroup.Colors[0])fmt.Println(decodedGroup.Colors[1])
}
2、使用第三方包
标准输出&格式化输出&解码
package mainimport ("fmt""github.com/goccy/go-json""os"
)type ColorGroup struct {ID intName stringColors []string
}func main() {group := ColorGroup{ID: 1,Name: "Reds",Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},}b1, err := json.Marshal(group)if err != nil {fmt.Println("error:", err)}println(os.Stdout.Write(b1)) //os.Stdout.Write(b1)将字节切片b(即JSON字符串的字节表示)写入到标准输出fmt.Println("---------------格式化输出----------------")// 使用 MarshalIndent 来格式化输出b2, err := json.MarshalIndent(group, "", " ") // 第二个参数是空字符串,表示不添加前缀;第三个参数是缩进字符串if err != nil {fmt.Println("error:", err)return}// 使用 fmt.Println 来打印字符串// MarshalIndent返回的是字节切片,我们需要使用string(b2)来将其转换为字符串fmt.Println(string(b2)) // 将字节切片转换为字符串并打印// 输出将会是格式化后的 JSON 字符串// 创建一个ColorGroup类型的变量来保存解码后的数据var decodedGroup ColorGroup// 将JSON字符串解码到ColorGroup结构体中err = json.Unmarshal([]byte(b1), &decodedGroup)if err != nil {fmt.Println("error:", err)return}// 打印解码后的数据fmt.Printf("ID: %d, Name: %s, Colors: %v\n", decodedGroup.ID, decodedGroup.Name, decodedGroup.Colors)// Output: ID: 1, Name: Reds, Colors: [Crimson Red Ruby Maroon]fmt.Println(decodedGroup.Colors[0])fmt.Println(decodedGroup.Colors[1])
}
请注意,在解码时,你需要将JSON字符串转换为[]byte
,并且传入结构体的指针(使用&
)。这样,解码后的数据才会被写入到结构体中
3、decode
package mainimport ("fmt""github.com/goccy/go-json"
)// Animal 定义结构体来表示单个JSON对象
type Animal struct {Name stringOrder string
}func main() {//创建一个JSON字节切片var jsonBlob = []byte(`[ {"Name": "Platypus", "Order": "Monotremata"}, {"Name": "Quoll", "Order": "Dasyuromorphia"} ]`)var animals []Animalerr := json.Unmarshal(jsonBlob, &animals)if err != nil {fmt.Println("error:", err)}fmt.Printf("%+v", animals)fmt.Println()// 打印解码后的数据for _, animal := range animals {fmt.Printf("Name: %s, Order: %s\n", animal.Name, animal.Order)}
}
4、注意
结构体
结构体必须是大写字母开头的成员才会被JSON
处理到,小写字母开头的成员不会有影响。
Mashal
时,结构体的成员变量名将会直接作为JSON
Object
的key
打包成JSON
;Unmashal
时,会自动匹配对应的变量名进行赋值,大小写不敏感。
Unmarshal
时,如果JSON
中有多余的字段,会被直接抛弃掉;如果JSON
缺少某个字段,则直接忽略不对结构体中变量赋值,不会报错。
package mainimport ("encoding/json""fmt"
)type Message struct {Name stringBody stringTime int64inner string
}func main() {var m = Message{Name: "Alice",Body: "Hello",Time: 1294706395881547000,inner: "ok",}b := []byte(`{"nAmE":"Bob","Food":"Pickle", "inner":"changed"}`)err := json.Unmarshal(b, &m)if err != nil {fmt.Printf(err.Error())return}fmt.Printf("%v", m)//Output: {Bob Hello 1294706395881547000 ok}
}
StructTag/结构体标签
如果希望手动配置结构体的成员和JSON
字段的对应关系,可以在定义结构体的时候给成员打标签:
使用omitempty
熟悉,如果该字段为nil
或0值(数字0,字符串"",空数组[]等),则打包的JSON
结果不会有这个字段。
案例一
package mainimport ("encoding/json""fmt"
)type Message struct {Name string `json:"msg_name"` // 对应JSON的msg_nameBody string `json:"body,omitempty"` // 如果为空置则忽略字段Time int64 `json:"-"` // 直接忽略字段
}func main() {var m = Message{Name: "Alice",Body: "",Time: 1294706395881547000,}data, err := json.Marshal(m)if err != nil {fmt.Printf(err.Error())return}fmt.Println(string(data))//Output:{"msg_name":"Alice"}
}
案例二
package mainimport ("encoding/json""fmt""log""time"
)// 定义一个用于JSON映射的结构体
type User struct {Name string `json:"username"` // 自定义字段名称映射Email string `json:"email"`LastSeen CustomTime `json:"last_seen"` // 嵌套对象Active bool `json:"-"` // 忽略此字段,即使JSON中存在也不解码
}// CustomTime 是一个用于表示时间的结构体
type CustomTime struct {time.Time
}// 实现 json.Unmarshaler 接口的 UnmarshalJSON 方法
func (ct *CustomTime) UnmarshalJSON(data []byte) error {var s stringif err := json.Unmarshal(data, &s); err != nil {return err}// 解析自定义时间格式parsedTime, err := time.Parse(time.RFC3339, s)if err != nil {return err}ct.Time = parsedTimereturn nil
}func main() {// 模拟从HTTP请求中获取的JSON数据jsonData := []byte(`{"username": "johndoe","email": "john.doe@example.com","last_seen": "2023-04-01T12:34:56Z","active": true}`)// 创建一个 User 实例var user User// 使用 json.Unmarshal 解码 JSON 数据if err := json.Unmarshal(jsonData, &user); err != nil {log.Fatal("Error unmarshaling JSON:", err)}// 打印解码后的信息fmt.Printf("Name: %s\n", user.Name)fmt.Printf("Email: %s\n", user.Email)fmt.Printf("Last Seen: %v\n", user.LastSeen)// Active 字段将不会被解码,即使JSON中存在fmt.Printf("Active: %v\n", user.Active)//输出://Name: johndoe//Email: john.doe@example.com// Last Seen: 2023-04-01 12:34:56 +0000 UTC//Active: false
}
5、更灵活地使用JSON
使用json.RawMessage
json.RawMessage
其实就是[]byte
类型的重定义。可以进行强制类型转换。
现在有这么一种场景,结构体中的其中一个字段的格式是未知的:
type Command struct {ID intCmd stringArgs *json.RawMessage
}
使用json.RawMessage
的话,Args
字段在Unmarshal
时不会被解析,直接将字节数据赋值给Args
。我们可以能先解包第一层的JSON
数据,然后根据Cmd
的值,再确定Args
的具体类型进行第二次Unmarshal
。
这里要注意的是,一定要使用指针类型*json.RawMessage
,否则在Args
会被认为是[]byte
类型,在打包时会被打包成base64
编码的字符串。
案例一
package mainimport ("encoding/json""fmt""log"
)type Command struct {ID intCmd stringArgs *json.RawMessage // 未解析的JSON片段
}func main() {//json字节切片jsonData := []byte(`{ "ID": 1, "Cmd": "example", "Args": ["arg1", "arg2"] }`)var cmd Command//解码/反序列化if err := json.Unmarshal(jsonData, &cmd); err != nil {log.Fatalf("Error unmarshaling JSON: %v", err)}fmt.Printf("Command: %+v\n", cmd)// 如果需要,可以进一步处理cmd.Args字段// 例如,将其解析为特定的Go类型var args []stringif err := json.Unmarshal(*cmd.Args, &args); err != nil {log.Printf("解析错误: %v", err)} else {fmt.Printf("Args: %v\n", args)}//输出//Command: {ID:1 Cmd:example Args:0xc0000080f0}//Args: [arg1 arg2]
}
案例二
package mainimport ("encoding/json""fmt""log"
)type Command struct {ID intCmd stringArgs *json.RawMessage // 未解析的JSON片段
}// UnmarshalJSON 自定义JSON解码方法,Command实现了Unmarshaler接口
func (c *Command) UnmarshalJSON(data []byte) error {fmt.Println("--------------使用自定义解码--------------")// 定义一个辅助结构体,用于解码除Args外的其他字段type alias Commandvar aux struct {alias // 嵌入别名类型以获取其他字段}// 先解码除Args外的所有字段if err := json.Unmarshal(data, &aux); err != nil {return err}fmt.Printf("Command ID: %+v, Cmd: %+v\n", aux.alias.ID, aux.alias.Cmd)// 将别名结构体中的字段复制到c中*c = Command(aux.alias)// 检查JSON中是否有Args字段,并处理它var m map[string]json.RawMessageif err := json.Unmarshal(data, &m); err != nil {// 如果这里出错,可能是因为JSON格式不正确,但我们可能仍然想要保留已经解析的字段// 因此,我们可以只记录一个错误,但不返回它log.Printf("Error parsing Args field: %v", err)} else {// 如果Args字段存在,将其赋值给c.Argsif rawArgs, ok := m["Args"]; ok {c.Args = &rawArgs // 注意这里我们取了rawArgs的地址var args []stringif err := json.Unmarshal(*c.Args, &args); err != nil {log.Printf("Error parsing Args contents: %v", err)} else {fmt.Printf("Args: %v\n", args)}}}// 如果没有错误,返回nilreturn nil
}func main() {//json字节切片jsonData := []byte(`{ "ID": 1, "Cmd": "example", "Args": ["arg1", "arg2"] }`)var cmd Command//解码/反序列化if err := json.Unmarshal(jsonData, &cmd); err != nil {log.Fatalf("Error unmarshaling JSON: %v", err)}
}
案例三
package mainimport ("encoding/json""fmt""log"
)type Command struct {ID intCmd stringArgs *json.RawMessage // 未解析的JSON片段
}// UnmarshalJSON 自定义JSON解码方法,Command实现了Unmarshaler接口
func (c *Command) UnmarshalJSON(data []byte) error {fmt.Println("--------------使用自定义解码--------------")// 检查JSON中是否有Args字段,并处理它var m map[string]json.RawMessageif err := json.Unmarshal(data, &m); err != nil {// 如果这里出错,可能是因为JSON格式不正确,但我们可能仍然想要保留已经解析的字段// 因此,我们可以只记录一个错误,但不返回它log.Printf("Error parsing Args field: %v", err)} else {// 如果Args字段存在,将其赋值给c.Argsif rawArgs, ok := m["Args"]; ok {c.Args = &rawArgs // 注意这里我们取了rawArgs的地址var args []stringif err := json.Unmarshal(*c.Args, &args); err != nil {log.Printf("Error parsing Args contents: %v", err)} else {fmt.Printf("Args: %v\n", args)}}}// 如果没有错误,返回nilreturn nil
}func main() {//json字节切片jsonData := []byte(`{ "ID": 1, "Cmd": "example", "Args": ["arg1", "arg2"] }`)var cmd Command//解码/反序列化if err := json.Unmarshal(jsonData, &cmd); err != nil {log.Fatalf("Error unmarshaling JSON: %v", err)}
}
调用的json.Unmarshal,并不是调用json.Unmarshaler,为什么会调用UnmarshalJSON
调用 json.Unmarshal
函数时,您并没有直接调用 json.Unmarshaler
接口的方法。但是,json.Unmarshal
函数在内部会检查目标类型是否实现了 json.Unmarshaler
接口。如果实现了该接口,json.Unmarshal
就会使用您为该类型定义的 UnmarshalJSON
方法来解码 JSON 数据。
这是 json.Unmarshal
函数内部逻辑的一部分,用于确定如何解码 JSON 数据。具体步骤如下:
json.Unmarshal
接收一个字节切片(包含 JSON 数据)和一个目标值的指针。- 它首先会检查目标值的类型是否实现了
json.Unmarshaler
接口。 - 如果实现了
json.Unmarshaler
接口,json.Unmarshal
就会调用该类型的UnmarshalJSON
方法,并将 JSON 数据的字节切片作为参数传递给它。 - 如果目标值没有实现
json.Unmarshaler
接口,json.Unmarshal
就会使用默认的解码逻辑来填充目标值的字段。
这种机制使得开发者能够灵活地控制 JSON 数据到 Go 结构体之间的转换过程。通过实现 json.Unmarshaler
接口,您可以:
- 处理 JSON 数据中不存在的字段。
- 自定义字段名称的映射规则。
- 处理 JSON 数据中的嵌套对象或数组。
- 执行额外的验证或数据处理逻辑。
以下是简单的示例,展示了如何为一个类型实现 json.Unmarshaler
接口
处理 JSON 数据中不存在的字段
假设我们有一个结构体,它能够处理JSON中可能缺失的字段,并且为这些字段提供默认值。
在这个例子中,Age
字段在JSON中不存在,因此它将被赋予其类型的零值(对于int
类型是0
)。
package mainimport ("encoding/json""fmt""log"
)type User struct {Name string `json:"name"`Age int `json:"age"`Email string `json:"email,omitempty"`
}func main() {var user User// JSON 中没有 "age" 字段,将使用 Age 的零值 0jsonData := []byte(`{"name": "John", "email": "john@example.com"}`)if err := json.Unmarshal(jsonData, &user); err != nil {log.Fatal(err)}fmt.Printf("Name: %s, Age: %d, Email: %s\n", user.Name, user.Age, user.Email)//Name: John, Age: 0, Email: john@example.com
}
自定义字段名称的映射规则
使用结构体标签中的json
键来指定JSON字段名。
在这个例子中,结构体的字段名和JSON字段名不匹配,我们通过在结构体标签中指定json
来实现映射。
package mainimport ("encoding/json""fmt""log"
)type User struct {Username string `json:"user_name"`Password string `json:"pass"`
}func main() {var user UserjsonData := []byte(`{"user_name": "johndoe", "pass": "secret"}`)if err := json.Unmarshal(jsonData, &user); err != nil {log.Fatal(err)}fmt.Printf("Username: %s, Password: %s\n", user.Username, user.Password)//Username: johndoe, Password: secret
}
处理 JSON 数据中的嵌套对象或数组
解码一个包含嵌套结构体的JSON数据。
在这个例子中,Address
是一个嵌套在 User
结构体中的对象。
package mainimport ("encoding/json""fmt""log"
)type Address struct {City string `json:"city"`Country string `json:"country"`
}type User struct {Name string `json:"name"`Address Address `json:"address"` // 嵌套对象
}func main() {var user UserjsonData := []byte(`{"name": "Jane", "address": {"city": "New York", "country": "USA"}}`)if err := json.Unmarshal(jsonData, &user); err != nil {log.Fatal(err)}fmt.Printf("Name: %s, Lives in %s, %s\n", user.Name, user.Address.City, user.Address.Country)//Name: Jane, Lives in New York, USA
}
执行额外的验证或数据处理逻辑
在UnmarshalJSON
方法中添加额外的验证逻辑。
在这个例子中,我们为User
类型实现了自定义的UnmarshalJSON
方法。在解码过程中,如果Age
字段的值是负数,将返回一个错误,这是一个额外的验证逻辑。
package mainimport ("encoding/json""fmt""log"
)type User struct {Name string `json:"name"`Age int `json:"age"`
}func (u *User) UnmarshalJSON(data []byte) error {type Alias User // 影子类型,避免递归调用 UnmarshalJSONaux := &Alias{Name: u.Name, Age: u.Age} // 使用辅助结构体来解耦if err := json.Unmarshal(data, aux); err != nil {return err}*u = User(*aux) // 将解耦的结构体赋值给当前结构体if u.Age < 0 { //年龄不能为负数return fmt.Errorf("age cannot be negative")}return nil
}func main() {var user UserjsonData := []byte(`{"name": "Alice", "age": -5}`)if err := json.Unmarshal(jsonData, &user); err != nil {log.Fatal(err)}fmt.Printf("Name: %s, Age: %d\n", user.Name, user.Age)
}
在上面的示例中,User
类型实现了 json.Unmarshaler
接口的 UnmarshalJSON
方法,使得 json.Unmarshal
函数在解码 JSON 数据时会调用这个方法,而不是使用默认的解码逻辑。这允许我们自定义解码逻辑,例如只接受特定格式的 JSON 数据。
使用interface{}
interface{}
类型在Unmarshal
时,会自动将JSON
转换为对应的数据类型:
JSON的boolean 转换为bool
JSON的数值 转换为float64
JSON的字符串 转换为string
JSON的Array 转换为[]interface{}
JSON的Object 转换为map[string]interface{}
JSON的null 转换为nil
需要注意的有两个。一个是所有的JSON
数值自动转换为float64
类型,使用时需要再手动转换为需要的int
,int64
等类型。第二个是JSON
的object
自动转换为map[string]interface{}
类型,访问时直接用JSON ``Object
的字段名作为key
进行访问。再不知道JSON
数据的格式时,可以使用interface{}
。
相关文章:
在Go语言中,可以这样使用Json
在Go语言中,处理JSON数据通常涉及编码(将Go结构体转换为JSON字符串)和解码(将JSON字符串转换为Go结构体)。Go标准库中的encoding/json包提供了这些功能。第三方插件可以使用"github.com/goccy/go-json"也有同…...

React useEffect Hook: 理解和解决组件双重渲染问题
在React中,useEffect可能会在组件的每次渲染后运行,这取决于它的依赖项。如果你发现useEffect运行了两次,并且你正在使用React 18或更高版本的严格模式(Strict Mode),这可能是因为在开发模式下,…...

【C语言】—— 动态内存管理
【C语言】——动态内存管理 一、动态内存管理概述1.1、动态内存的概念1.2、动态内存的必要性 二、 m a l l o c malloc malloc 函数2.1、函数介绍2.2、应用举例 三、 c a l l o c calloc calloc 函数四、 f r e e free free 函数4.1、函数介绍4.2、应用举例 五、 r e a l l o …...

Oracle到PostgreSQL的不停机数据库迁移
1970 年,数据库之父 Edgar Frank Codd 发表了“数据的关系模型”论文,该论文为往后的关系型数据库的发展奠定了基础。1979 年,基于关系模型理论的数据库产品 Oracle 2 首次亮相,并在过去的三四十年时间里,横扫全球数据…...

OpenAI 发布新款大型语言模型 GPT-4o,带大家了解最新ChatGPT动态。
OpenAI 发布新款大型语言模型 GPT-4o 昨日OpenAI 举办了一场线上活动,正式发布了其最新研发的 AI 模型 GPT-4o,并详细介绍了该模型的强大功能和未来发展规划。此次发布标志着 AI 技术的重大突破,为用户提供了更加便捷、高效的 AI 工具&#…...

网络编程套接字(一) 【简单的Udp网络程序】
网络编程套接字<一> 理解源端口号和目的端口号PORT VS PID认识TCP协议和UDP协议网络字节序socket编程接口sockaddr结构简单的UDP网络程序服务端创建套接字服务端绑定运行服务器客户端创建套接字关于客户端的绑定问题启动客户端启动客户端本地测试INADDR_ANY 理解源端口号…...
【CANoe】CAPL中生成报告常用的测试函数
文章目录 一、常用函数1、测试标题、描述、Comment2、测试步骤3、延时4、报告中插入图片5、报告中插入窗口截图二、实例源码三、报告效果一、常用函数 1、测试标题、描述、Comment testCaseTitle("TC 3.1", "Test Case 3.1"); testCaseDescription...
WEB后端复习——MVC、SSM【含登录页面代码】
MVC(Model-View-Controller)是一种软件设计模式,用于将应用程序分解为三个相互关联的组件:模型(Model)、视图(View)和控制器(Controller)。这种模式在构建用户…...

灵卡科技HDMI音视频采集及H.264编码一体化采集卡—LCC260
推荐一款由灵卡科技倾力打造的高品质HDMI音视频采集卡——LCC260。以创新的技术,精湛的工艺和卓越的性能,为您提供全方位的音视频解决方案。 LCC260是一款集HDMI音视频采集与H.264编码于一身的全功能采集卡。它的输入端配备了最先进的HDMI 1.4a标准接口&…...

智能自助终端主板RK3288/RK3568在酒店前台自助机方案的应用,支持鸿蒙,支持免费定制
酒店前台自助机解决方案是一款基于自助服务终端,能够让客人通过简单的操作完成入住登记/退房的解决方案,大幅提高酒店的工作效率,提升客人体验,降低人力成本。 该方案解决了以下传统前台登记入住方式的痛点: 1、人流量…...
Visual Studio环境搭载
环境搭建步骤: 下载软件 安装软件 运行软件 1 下载软件 在百度搜索 visual studio,选择 如下图中的选项 进入Visual Studio 官网后,选择 下载Windows版,并选择Community 2017 社区版本进行下载保存软件到电脑中 2 安装软件 双击…...

添砖Java之路(其八)——继承,final关键字
目录 继承: super关键字: 方法重写: 继承特点: 继承构造方法: final关键字: 继承: 意义:让类于类之间产生父类于子类的关系,子类可以直接使用父类中的非私有成员(包…...

一篇详解Git版本控制工具
华子目录 版本控制集中化版本控制分布式版本控制 Git简史Git工作机制Git和代码托管中心局域网互联网 Git安装基础配置git的--local,--global,--system的区别 创建仓库方式1git init方式2git clone git网址 工作区,暂存区,本地仓库…...

谷歌邮箱2024最新注册教程
大家好,我是蓝胖子,今天教大家如何注册谷歌邮箱 谷歌邮箱的注册后面的用途会经常用得到 首先,需要魔法自行解决 第一步:打开谷歌官网 www.google.com 确保谷歌官网能正常打开 第二步:创建账号 接下来可能会遇到这…...
Spring事务深度解析
Spring事务深度解析 介绍 在现代的软件开发中,事务管理是一个非常重要的话题。Spring框架提供了强大的事务管理功能,使得开发人员能够轻松地处理数据库操作的一致性和并发性问题。本文将深入探讨Spring事务的原理和使用方法。 什么是事务?…...

机器学习周报第41周
目录 摘要Abstract一、文献阅读1.1 摘要1.2 背景1.3 论文方法1.3.1 局部特征提取1.3.2 局部特征转换器 (LoFTR) 模块1.3.4 建立粗粒度匹配1.3.5 精细匹配 1.4 损失1.5 实现细节1.6 实验1.6.1 单应性估计1.6.2 相对位姿估计 二、论文代码总结 摘要 本周阅读了一篇特征匹配领域的…...

gin框架学习笔记(三) ——路由请求与相关参数
参数种类与参数处理 查询参数 在讲解查询参数的定义之前,我们先来看一个例子,当我打开了CSDN,我现在想查看我的博客浏览量,那么我就需要点击我的头像来打开我的个人主页,像下面这样: 我们现在把浏览器的网址取下来,…...
HTML常用标签-多媒体标签(图片、音频、视频)
多媒体标签 1 图片标签2 音频标签3 视频标签 1 图片标签 img(重点) 图片标签,用于在页面上引入图片 代码 <!-- src用于定义图片的连接 title用于定义鼠标悬停时显示的文字 alt用于定义图片加载失败时显示的提示文字 --> <img src"路径" title"悬停显…...
Flutter 中的 AnimatedIcon 小部件:全面指南
Flutter 中的 AnimatedIcon 小部件:全面指南 AnimatedIcon是Flutter Material组件库中的一个独特动画组件,它允许开发者在两个图标之间进行平滑的过渡动画。这使得它非常适合用于表示应用程序的状态变化,如菜单打开/关闭、搜索打开/关闭等。…...

0510Goods的Maven项目
0510Goods的Maven项目包-CSDN博客 数据库字段 商品主页 修改页面 点击商品主页更改信息, 跳转到修改页面, 并保留初始信息。 商品类别最多选取三项,最少选取一项 添加界面 商品类别最多选取三项,最少选取一项...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...