在Go语言中,可以这样使用Json

在Go语言中,处理JSON数据通常涉及编码(将Go结构体转换为JSON字符串)和解码(将JSON字符串转换为Go结构体)。Go标准库中的encoding/json包提供了这些功能。第三方插件可以使用"github.com/goccy/go-json"也有同样的功能

 Marshal函数将会递归遍历整个对象,依次按成员类型对这个对象进行编码,类型转换规则如下:

  • bool类型 转换为JSONBoolean

  • 整数,浮点数等数值类型 转换为JSONNumber

  • string 转换为JSON的字符串(带""引号)

  • struct 转换为JSONObject,再根据各个成员的类型递归打包

  • 数组或切片 转换为JSONArray

  • []byte 会先进行base64编码然后转换为JSON字符串

  • map转换为JSONObjectkey必须是string

  • interface{} 按照内部的实际类型进行转换

  • nil 转为JSONnull

  • 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 Objectkey打包成JSONUnmashal时,会自动匹配对应的变量名进行赋值,大小写不敏感。

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 数据。具体步骤如下:

  1. json.Unmarshal 接收一个字节切片(包含 JSON 数据)和一个目标值的指针。
  2. 它首先会检查目标值的类型是否实现了 json.Unmarshaler 接口。
  3. 如果实现了 json.Unmarshaler 接口,json.Unmarshal 就会调用该类型的 UnmarshalJSON 方法,并将 JSON 数据的字节切片作为参数传递给它。
  4. 如果目标值没有实现 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类型,使用时需要再手动转换为需要的intint64等类型。第二个是JSONobject自动转换为map[string]interface{}类型,访问时直接用JSON ``Object的字段名作为key进行访问。再不知道JSON数据的格式时,可以使用interface{}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/11832.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git | git log 和 git status 的区别

如是我闻&#xff1a; git log和git status是Git中的两个非常有用的命令&#xff0c;它们用于不同的目的&#xff0c;并提供不同类型的信息。 git log git log命令用于显示一个或多个分支的提交历史记录。这个命令会列出提交历史&#xff0c;包括每次提交的SHA-1哈希值、提交…

程控水冷阻性负载主要工作方式

程控水冷阻性负载是一种先进的电力设备&#xff0c;主要用于电力系统的测试和研究。它的主要工作方式是通过控制水冷系统的温度&#xff0c;来模拟不同的阻性负载条件&#xff0c;从而对电力设备进行各种性能测试。 首先&#xff0c;我们需要了解什么是阻性负载。阻性负载是指那…

博弈智能的特点

博弈智能是指通过算法和模型对博弈过程进行分析和决策的智能系统。在博弈中&#xff0c;各方参与者追求自身利益和目标&#xff0c;会采取各种策略来达到自己的目标。其中&#xff0c;包括了一些不正当手段&#xff0c;如诡计和欺骗&#xff08;诡&#xff09;&#xff08;诈&a…

代码随想录算法训练营Day 42| 动态规划part04 | 01背包问题理论基础I、01背包问题理论基础II、416. 分割等和子集

代码随想录算法训练营Day 42| 动态规划part04 | 01背包问题理论基础I、01背包问题理论基础II、416. 分割等和子集 文章目录 代码随想录算法训练营Day 42| 动态规划part04 | 01背包问题理论基础I、01背包问题理论基础II、416. 分割等和子集01背包问题理论基础一、01背包问题二、…

WSL设置启动时自动启动docker服务或其他服务

方式一: Windows系统的WSL,当windows关机再开机后,WSL等于是重新开机的,默认情况下,不会启动Docker服务。例如在Ubuntu 22.04中,需要使用命令 service docker start来启动。由于我习惯关机断电,因此每天开机打开WSL后都要手动输入这个命令,非常麻烦。所以找了一个方法…

Redis教程——哨兵

在上篇文章我们学习了Redis教程——主从复制&#xff0c;这篇文章我们学习Redis教程——哨兵监控。 在主从复制中如果主机发生宕机&#xff0c;从机Redis会一直等到主机的恢复&#xff0c;这样会导致只能进行读操作&#xff0c;不能进行写操作&#xff0c;这大大降低了系统的高…

资料同化 | 搭建docker环境-1

Community Gridpoint Statistical Interpolation (GSI) system DTC 是一个分布式设施&#xff0c;NWP 社区可以在这里测试和评估用于研究和操作的新模型和技术。 DTC的目标包括&#xff1a; 链接研究和操作社区 研究成果转化为实际操作的速度 加快改善天气预报 开发和测试有…

Cocos Creator 3.8.x 透明带滚动功能的容器

ScrollView 是一种带滚动功能的容器 1、删除ScrollView下Sprite组件的SpriteFrame 2、ScrollView下scrollBar的Sprite组件的Color设为&#xff1a;FFFFFF00 3、ScrollView下view的Graphics组件的FillColor设为&#xff1a;FFFFFF00

IP代理如何帮助SEO进行优化?

IP代理在SEO优化中扮演着重要的角色&#xff0c;它通过多种方式帮助提升网站的搜索排名和可见性。以下是IP代理如何帮助SEO进行优化的详细阐述&#xff1a; 第一点&#xff0c;数据采集与分析&#xff1a;在SEO过程中&#xff0c;大量的数据是必不可少的。通过使用IP代理&…

如何区分os.walk()与os.scandir()

os.walk() import os for dirpath, dirname, files in os.walk(./):# dirpath 当前——路径# dirname 当前——路径——下——文件夹名——列表# files 当前——路径——下——文件——列表dirpath 当前路径 ./ dirname 当前路径下面文件夹名称组成的列表&#xff0c;共3个文…

c++ std::shared_ptr学习

背景 c中智能指针shared_ptr用于自动管理资源&#xff0c;通过引用计数来记录资源被多少出地方使用。在不使用资源时&#xff0c;减少引用计数&#xff0c;如果引用计数为0&#xff0c;表示资源不会再被使用&#xff0c;此时会释放资源。本文记录对c中std::shared_ptr的源码学习…

攻防世界PHP2

1、打开靶机链接http://61.147.171.105:49513/&#xff0c;没有发现任何线索 2、尝试访问http://61.147.171.105:49513/index.php&#xff0c;页面没有发生跳转 3、尝试将访问 尝试访问http://61.147.171.105:49513/index.phps index.php 和 index.phps 文件之间的主要区别在于…

GNU Radio创建时间戳 C++ OOT块

文章目录 前言一、创建自定义的 C OOT 块1、创建 timestamp_sender C OOT 模块①、创建 timestamp_sender OOT 块②、修改 C 代码 2、创建 timestamp_receiver C OOT 模块①、创建 timestamp_receiver OOT 块②、修改 C 代码 3、创建 delayMicroSec C OOT 模块①、创建 delayMi…

Vue3实战笔记(20)—封装头部导航组件

文章目录 前言一、封装头部导航栏二、使用步骤总结 前言 Vue 3 封装头部导航栏有助于提高代码复用性、统一风格、降低维护成本、提高可配置性和模块化程度&#xff0c;同时还可以实现动态渲染等功能&#xff0c;有利于项目开发和维护。 一、封装头部导航栏 封装头部导航栏&am…

HFSS学习-day4-建模操作

通过昨天的学习&#xff0c;我们已经熟悉了HFSS的工作环境&#xff1b;今天我们来讲解HFSS中创建物体模型的县体步骤和相关操作。物体建模是HFSS仿真设计工作的第一步&#xff0c;HFSS中提供了诸如矩形、圆面、长方体圆柱体和球体等多种基本模型(Primitive)&#xff0c;这些基本…

新书速览|MATLAB科技绘图与数据分析

提升你的数据洞察力&#xff0c;用于精确绘图和分析的高级MATLAB技术。 本书内容 《MATLAB科技绘图与数据分析》结合作者多年的数据分析与科研绘图经验&#xff0c;详细讲解MATLAB在科技图表制作与数据分析中的使用方法与技巧。全书分为3部分&#xff0c;共12章&#xff0c;第1…

tp8 设置空控制器和空方法

1、空控制器 单应用模式下&#xff0c;我们可以给项目定义一个Error控制器类 <?phpnamespace app\controller;class Error {/*** 空控制器中重写魔术方法__call可以实现自定义错误提示&#xff0c;在这里可以提示找不到控制器* 注意&#xff1a;在基础控制器BaseControll…

精英都是时间控!职场精英的完美一天~~~谷歌FB都在用的时间管理术!

如何超高效使用24小时 每个人的一天都只有24小时&#xff0c;使用时间的方法将决定整个人生。时间管理术并不提倡把自己忙死榨干&#xff0c;而是通过在合适的时间做合适的事情&#xff0c;把大脑机能发挥到极致&#xff0c;从而提高效率&#xff0c;节省下更多时间用于生活与…

(项目)-KDE巡检报告(模板

金山云于12月26日对建行共计【30】个KDE集群,合计【198】台服务器进行了巡检服务。共发现系统风险【135】条,服务风险【1912】条,服务配置风险【368】条。 一、系统风险 1、风险分析(图片+描述) (1)磁盘使用率高 问题描述多个集群的多台服务器磁盘使用率较高,远超过…

答辩PPT模版如何选择?aippt快速生成

这些网站我愿称之为制作答辩PPT的神&#xff01; 很多快要毕业的同学在做答辩PPT的时候总是感觉毫无思路&#xff0c;一窍不通。但这并不是你们的错&#xff0c;对于平时没接触过相关方面&#xff0c;第一次搞答辩PPT的人来说&#xff0c;这是很正常的一件事。一个好的答辩PPT…