go 结构体 - 值类型、引用类型 - 结构体转json类型 - 指针类型的种类 - 结构体方法 - 继承 - 多态(interface接口) - 练习

目录

一、结构体

1、python 与 go面向对象的实现:

2、初用GO中的结构体:(实例化一个值类型的数据(结构体))

输出结果不同的三种方式 

3、实例化一个引用类型的数据(结构体)

4、引用类型(指针类型) vs 值类型(两者的区别)

引用类型(指针类型) - 值类型内存拓扑图:

5、结构体匿名字段、匿名结构体

6、结构体的嵌套

7、结构体转json类型

二、指针类型的种类(结构体指针、数据变量指针、指针数组、数组指针)

三、结构体方法(普通方法、指针方法)

四、结构体继承:

五、结构体多态:(interface接口的运用)

1、空接口的定义:

2、接口如何实现自定义error呢?

1、练习:判断Role(角色)是否存活

2、练习:实现发邮件功能

3、练习:定义标准化返回(json格式)


一、结构体

结构体(Struct)是一种在Go语言中用于定义复合数据类型的机制。它允许你将不同类型的数据组合在一起,形成一个自定义的数据类型,以便更方便地管理和操作相关数据。

在Go语言中,通过type关键字和字段列表来定义结构体。每个字段都可以有自己的数据类型,类似于其他编程语言中的类的成员变量。结构体中的字段可以包含任意类型的数据,包括基本数据类型(如整数、浮点数、字符串等)和其他自定义类型(如其他结构体、数组、切片等)。

结构体中可以定义多个字段,类似于python中class类的属性

以下是一个简单的例子来说明如何定义和使用结构体:

package mainimport "fmt"// 定义一个Person结构体
type Person struct {Name stringAge  int
}func main() {// 创建一个Person类型的变量var person1 Person// 设置person1的字段值person1.Name = "Alice"person1.Age = 30// 打印person1的字段值fmt.Println(person1) // 输出:{Alice 30}// 创建并初始化Person结构体的另一个变量person2 := Person{Name: "Bob",Age:  25,}// 打印person2的字段值fmt.Println(person2) // 输出:{Bob 25}
}

在上述示例中,我们通过type关键字定义了一个名为Person的结构体。该结构体有两个字段,分别为NameAge,分别用来存储人的姓名和年龄。

main函数中,我们创建了两个Person类型的变量person1person2,并分别设置了它们的字段值。可以通过运算符来访问结构体变量的字段。

1、python 与 go面向对象的实现:

python 支持面向对象的  --》 class 类

go        不支持面向对象编程,可以使用结构体来实现类似的功能

  python => 面向对象class Student(object):def __init__(self, id, name, age):self.id = id....go => 支持结构体
type struct_name struct{field_name1 field_typefield_name2 field_typefield_name3 field_type...
}

2、初用GO中的结构体:(实例化一个值类型的数据(结构体))

// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}func main(){// 实例化一:实例化一个值类型的数据(结构体)// 实例化的时候,可以只初始化部分数据zrp := Student{id:     1,name:   "zrp",}//输出结果不同的三种方式fmt.Printf("%v\n", zrp)fmt.Printf("%+v\n", zrp)fmt.Printf("%#v\n", zrp)// 初始化的时候,如果不指定字段名,就需要每个字段都赋值// 否则会报错:too few values in Student{…}wbw :=Student{2,"wbw",20, "nongda"}// 值类型的数据要看地址的话,需要加&fmt.Printf("%#v,地址:%p\n", wbw, &wbw)}输出:
{1 zrp 0 }
{id:1 name:zrp age:0 school:}
main.Student{id:1, name:"zrp", age:0x0, school:""}
main.Student{id:2, name:"wbw", age:0x14, school:"nongda"},地址:0xc000100540

输出结果不同的三种方式 

fmt.Printf("%v\n", zrp)
fmt.Printf("%+v\n", zrp)
fmt.Printf("%#v\n", zrp)

输出:

{1 zrp 0 }
{id:1 name:zrp age:0 school:}
main.Student{id:1, name:"zrp", age:0x0, school:""}

3、实例化一个引用类型的数据(结构体)

package mainimport "fmt"// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}func main(){// 实例化一个引用类型// 使用new实例化开辟一片内存空间,创建一个实例对象,返回这个对象的内存地址mq := new(Student)   //使用new实例化开辟一片内存空间 , mq是引用类型的数据mq.id = 3            //mq.name = "mq"mq.age = 18fmt.Printf("%#v,地址:%p\n", mq, mq)
}输出:
&main.Student{id:3, name:"mq", age:0x12, school:""},0xc00000a028

4、引用类型(指针类型) vs 值类型(两者的区别)

package mainimport "fmt"// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}func main(){// 实例化一个值类型的数据wbw :=Student{2,"wbw",20, "nongda"}// 实例化一个引用类型的数据mq := new(Student)mq.id = 3mq.name = "mq"mq.age = 18// 引用类型(指针类型) vs 值类型 区别// 引用类型 => 指向了一个内存数据,注意:如果要修改的话,一同变化mq2 := mqmq2.name = "米强"fmt.Printf("type:%T,values:%+v,address:%p\n",mq, mq,mq)fmt.Printf("type:%T,values:%+v,address:%p\n",mq2, mq2,mq2)// 值类型:两份数据,相互不影响wbw2 := wbwwbw2.name = "王百文"fmt.Printf("type:%T,values:%+v,address:%p\n",wbw, wbw, &wbw)fmt.Printf("type:%T,values:%+v,address:%p\n",wbw2, wbw2,&wbw2)
}输出:
type:*main.Student,values:&{id:3 name:米强 age:18 school:},address:0xc0001004e0
type:*main.Student,values:&{id:3 name:米强 age:18 school:},address:0xc0001004e0
type:main.Student,values:{id:2 name:wbw age:20 school:nongda},address:0xc0001004b0
type:main.Student,values:{id:2 name:王百文 age:20 school:nongda},address:0xc000100570

引用类型(指针类型) - 值类型内存拓扑图:

5、结构体匿名字段、匿名结构体

package mainimport "fmt"// 结构体匿名字段 => 如果没有定义字段名,会用类型的名字直接充当字段名
type Stu struct {stringint
}func main(){// 结构体匿名字段实例化st1 := Stu{"abc", 100}fmt.Printf("st1:%+v\n", st1)// 匿名结构体: 适合一次性使用stu2 := struct {name stringage int}{"cali", 30}fmt.Printf("st2:%+v\n", stu2)
}输出:
st1:{string:abc int:100}
st2:{name:cali age:30}

6、结构体的嵌套

package mainimport "fmt"// 结构体的嵌套
type Book struct {title stringAuthor struct{name, tel stringage int}
}func main(){// 嵌套结构体的实例化b1 := Book{title: "GO从入门到精通"}b1.Author.name = "cici"b1.Author.tel = "186xxxxxxxx"fmt.Printf("b1:%+v\n", b1)
}输出:
b1:{title:GO从入门到精通 Author:{name:cici tel:186xxxxxxxx age:0}}

7、结构体转json类型

package mainimport ("encoding/json""fmt"
)// Web开发,数据定义都是结构体类型 结构体数据 <=> json <=>前端
// 加Tag(两个反引号``): Tag加上json配置项:他当将结构体转换成json的时候读取该配置
// Student结构体内的数据转换为json格式
type Student struct{// 转换json格式Id int			`json:"id"`Name string		`json:"username"`// 设置成“-” => 表示忽略该字段School string	`json:"-"`// 如果没有配置 => 使用默认字段名School2 string// omitempty如果当前字段School3有值的,会显示出来,如果没有值就不会显示School3 string 	`json:"school,omitempty"`
}// 使用json模块
// go结构体数据 <=> json <=>前端
func main(){// 实例化s1 := Student{Id:     1,Name:   "user1",School: "nongda",School3: "nongda3",  // omitempty会导致如果School3没有值就不会显示School3字段}// 用于进行go的异常处理bmarshal, err := json.Marshal(s1)if err == nil {// 输出转换后的json格式数据fmt.Println(string(bmarshal))}else{// 输出其中的错误fmt.Println("err:", err)}
}输出:
{"id":1,"username":"user1","School2":"","school":"nongda2"}

二、指针类型的种类(结构体指针、数据变量指针、指针数组、数组指针)

package mainimport "fmt"// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}func main(){// 结构体指针mc := &Student{id: 4,name: "mc",}fmt.Printf("type:%T, values:%+v\n", mc, mc)// 结构体指针中,可以使用简化的语法fmt.Printf("%+v, %s\n", mc, (*mc).name)fmt.Printf("%+v, %s\n", mc, mc.name)// 数据变量指针获取数据的方法var n1 *int  // 定义n1为int指针n2 := 10     // 给n2赋值n1 = &n2     // 将n2的地址传给n1指针*n1 = 20     // 给n1指针赋值为20fmt.Printf("type:%T,address:%p, value:%d\n",n1, n1, *n1)fmt.Printf("address:%p, value:%d\n",&n2, n2)// 指针数组 parr是一个数组,有4个元素,每个元素都是一个int类型的指针var parr [4]*inta := 10parr[2] = &afmt.Printf("value:%v, address:%v\n", *parr[2], parr[2])// 数组指针:是一个指针,指向了一个数组类型的数据(访问数据的时候,可以使用简化方式)var parr2 *[4]intarr := [4]int{1,2,3,4}parr2 = &arrfmt.Printf("arrvalue:%v, value:%v, value:%v\n", parr2, (*parr2)[0], parr2[0])
}输出:
type:*main.Student, values:&{id:4 name:mc age:0 school:}
type:*int,address:0xc0000a60a0, value:20
address:0xc0000a60a0, value:20
&{id:4 name:mc age:0 school:}, mc
&{id:4 name:mc age:0 school:}, mc
value:10, address:0xc00000e138
arrvalue:&[1 2 3 4], value:1, value:1

三、结构体方法(普通方法、指针方法)

package mainimport "fmt"
// 结构体方法的实现
// 在普通函数前加上一个接收者(receiver)
// func (s receiverType) funcName(args...)  --》 结构体方法的定义// 定义一个Student结构体
type Student struct {id intname stringage uintschool string
}// 为Student结构绑定一个changeSchool方法 (值类型的结构体,在函数内部修改数据并不会影响函数外面)
func (s Student) changeSchool(school string){s.school = school
}// 为*Student(指针)结构体绑定一个changeSchool2方法 (指针类型的结构体,在函数中修改了数据会影响外部的数据)
func (s *Student) changeSchool2(school string){s.school = school
}// 因此我们在调用结构体方法的时候,需要注意是什么结构体类型
func main(){// 实例化一个值类型的数据// 实例化一个结构体// 实例化的时候,可以只初始化部分数据zrp := Student{id:     1,name:   "zrp",} // 结构体指针mc := &Student{id: 4,name: "mc",}// 使用结构体方法// 值结构(普通结构体)// 普通结构:外面的数据和函数中的数据是两个不同的数据,在函数内修改,不影响函数外zrp.changeSchool("湖南农业大学")fmt.Printf("新学校是:%v\n", zrp.school)// 输出为:新学校是: (没有传入值)// 指针结构体:外面和函数中是同一个数据,在函数中修改了,影响函数外mc.changeSchool2("湖南农业大学")fmt.Printf("新学校是:%v\n", mc.school)}输出:
新学校是:
新学校是:湖南农业大学

四、结构体继承:

package mainimport "fmt"// 创建Author作者结构体
type Author struct{// 定义字段name, tel stringage int
}// 继承:Book继承了Author结构体
type Book struct {title stringauthor Author
}// 给Book添加了一个结构体方法
func (b *Book) Print(){  fmt.Printf("%s的作者是:%s\n", b.title, b.author.name)
}func main(){// 实例化方法// 先实例化Book,在将Author继承给Bookb1 := Book{title: "《Go入门到精通》"}b1.author.name = "TeacherWen"b1.author.tel = "187xxxxxxx"fmt.Printf("%+v\n",b1)b1.Print()// 先实例化Author, 再把Author赋值给Booka1 := Author{name: "TeacherFeng"}b2 := Book{title: "《Docker从入门到精通》", author: a1}fmt.Printf("%+v\n",b2)b2.Print()
}输出:
{title:《Go入门到精通》 author:{name:TeacherWen tel:187xxxxxxx age:0}}
《Go入门到精通》的作者是:TeacherWen
{title:《Docker从入门到精通》 author:{name:TeacherFeng tel: age:0}}
《Docker从入门到精通》的作者是:TeacherFeng

五、结构体多态:(interface接口的运用

多态:一个接口多个形态(为多个不同的数据类型提供统一的接口)
        其实就是一个功能,展现多种形态
        多态是指同一种操作或方法可以在不同的对象上产生不同的行为。

Go语言中实现多态需要用到interface

Interface接口类型可以定义一组方法(而非变量),并且不需要实现


// 定义一个函数MyPrint,我们可以通过MyPrint来使多个数据进行打印操作,但是当前MyPrint并不是多态的,需要下面的interface接口操作
// func MyPrint(s string){
// 	 fmt.Println("")
// }// 如果WePay结构体实现了PayInterface接口所有的方法,那么可以说
// WePay结构是是PayInterface类型
type PayInterface interface {// 声明一些方法,但不需要实现// 方法名(参数列表) 返回值 --》pay()就为方法接口,他没有参数和返回值pay()// 可以定义多个方法接口// pay2()、// print()// 运行print()方法后报错:AliPay does not implement PayInterface (missing print method) 和 WePay does not implement PayInterface (missing print method)// 说明AliPay 和 WePay 没有实现print() 方法// 如果说WePay结构体和AliPay结构体实现了PayInterface接口所有的方法,那么可以说这个结构体是PayInterface的可以实现的接口类型。// 下面我们将要实现微信支付和支付宝支付操作// 定义微信支付结构体
type WePay struct {name string
}// WePay实现了pay方法 等于  WePay实现PayInterface接口(wepay可以看作是PayInterface类型(上面定义的interface接口类型结构体))
func (w WePay) pay(){fmt.Printf("This is WePay:%s\n", w.name)
}// 定义支付宝支付结构体
type  AliPay struct {name string
}// AliPay实现PayInterface接口
func (a AliPay) pay(){fmt.Printf("This is AliPay:%s\n", a.name)
}// 定义函数payment用于实现PayInterface接口的pay()方法
func payment(p PayInterface){p.pay()
}func main(){// 实例化w1 和 a1,分别用于微信支付和支付宝支付w1 := WePay{name: "cici"}a1 := AliPay{name: "aiai"}// 调用payment函数传入实例,实现WePay和AliPay payment(w1)payment(a1)
}输出:
This is WePay:cici
This is AliPay:aiai

1、空接口的定义:

空接口可以表示任意类型的值。空接口的作用在于可以在不确定类型的情况下,用于保存和传递各种不同类型的值。由于空接口可以表示任意类型的值,所以它在某些场景下非常有用,比如在函数参数中,可以接受不同类型的参数,或者在数据结构中,可以存储不同类型的元素。

package mainimport "fmt"// 空接口
type Empty interface {}// 该test函数可以接收任意类型的数据,空接口的定义方式
func test(f interface{}){fmt.Printf("%v\n",f)
}func main(){// 空接口的使用// 该实例希望它的方法是string类型,但是它的value值可以是任意类型的,如希望m1定义为:m1 = {"name":"cici", "age":20}这种value可以是任意类型的,因此我们可以定义一个空接口Empty interface// Empty结构体定义方式m1 :=map[string]Empty{"name":"cici","age": 20,}//interface{}方法定义方式m2 :=map[string]interface{}{"name":"aiai","age": "18",}fmt.Printf("%v\n%v\n", m1, m2)
}输出:
map[age:20 name:cici]
map[age:18 name:aiai]

2、接口如何实现自定义error呢?

package mainimport ("fmt"//"errors"
)// 定义NameCheck函数,用于返回Error使用
// 如果name值为空,返回一个错误,否则就返回nil
func NameCheck(name string) error {  // 返回数据的类型是error类型if name == ""{// return errors.New("名字不能为空") // 通过errors包内New函数来进行error的提示, 比较复杂// 输出为:名字不能为空// 进行自定义错误(优点是比errors包内调用New方法简单快捷很多)return NameEmptyError{msg:"名字不能为空", code:1001}// 输出为:出错了:名字不能为空}return nil
}// 自定义错误 => 给NameEmptyError实现一个Error方法,它就是一个error类型了
type NameEmptyError struct {msg stringcode int
}// 定义NameEmptyError结构体方法Error()
func (e NameEmptyError) Error() string{// e.msg表示错误的信息return "出错了:"+e.msg
}func main(){// 定义变量namename := ""// 调用NameCheck函数err := NameCheck(name)if err != nil{// 出现错误,输出错误fmt.Println(err)}else{fmt.Println(name)}
}

1、练习:判断Role(角色)是否存活

定义Role(角色) => 属性:name, blood, isAlive(是否存活)

                       isAlive => 判断blood是<=0 True or False

package mainimport "fmt"// 定义结构体
type Role struct {name stringblood int
}// 非指针型的绑定(将r 绑定为 Role 结构体) isAlive() 是一个函数
func (r Role) isAlive() bool{if r.blood <= 0{return false}else{return true}
}// 指针型的绑定
//func (r *Role) isAlive() bool {
//	if r.blood <= 0{
//		return false
//	}else{
//		return true
//	}
//}func main(){// 创建实例类型role1 := Role{"role1", 90}role2 := Role{"role2", 0}// 打印数据fmt.Printf("%s:%v\n", role1.name, role1.isAlive())fmt.Printf("%s:%v\n", role2.name, role2.isAlive())
}输出:
role1:true
role2:false

2、练习:实现发邮件功能

功能介绍:

普通用户:结构体User => 字段:username, email, ShowUserInfo(), SendMail()

Root用户:结构体Root => 字段:username, email, ShowSysInfo(), SendMail()

邮件告警的功能 => sendNotification函数 --》可以接受所有权限用户

普通用户User和Root用户都能够使用sendNotification函数 => 并实现对对象的SendMail()

package mainimport "fmt"// 定义User结构体,内存字段username(用户名)、email(邮件地址)
type User struct {username stringemail string
}// 定义Root结构体,内存字段username(用户名)、email(邮件地址)
type Root struct {username stringemail string
}// 定义ShowUserInfo()结构体方法,调用User结构体,实现展示用户信息的功能
func (u User) ShowUserInfo(){fmt.Println("这是User的userInfo, User为:", u.username)
}// 定义SendMail()结构体方法,调用User结构体,实现发送用户邮件的功能
func (u User) SendMail(){fmt.Printf("User:%s正在发送邮件到%s\n", u.username, u.email)
}// 定义ShowSysInfo()结构体方法,调用Root结构体,实现展示Root信息的功能
func (r Root) ShowSysInfo(){fmt.Println("这是Root的sysInfo, Root为:", r.username)
}// 定义SendMail()结构体方法,调用Root结构体,实现Root发送邮件的功能
func (r Root) SendMail(){fmt.Printf("Root:%s正在发送邮件到%s\n", r.username, r.email)
}// 定义SendMailInterface结构体,内存SendMail()结构体方法
type SendMailInterface interface {SendMail()
}// 定义sendNotification函数,作用是接收参数并作为SendMail的对象
func sendNotification(s SendMailInterface){s.SendMail()
}func main()  {// 结构体实例化r := Root{username: "root", email: "root@sc.com"}u := User{username: "user1", email: "user1@sc.com"}// 调用sendNotification函数,并传入实例参数r.ShowSysInfo()sendNotification(r)u.ShowUserInfo()sendNotification(u)
}输出:
这是Root的sysInfo, Root为: root
Root:root正在发送邮件到root@sc.com
这是User的userInfo, User为: user1
User:user1正在发送邮件到user1@sc.com

3、练习:定义标准化返回(json格式)

package main/*
// 定义返回的数据格式,将返回的数据用json的方式打印出来
// Code, Message, Data
// s.json() => 将它转换成json格式(string)后端开发:API => 访问url => 返回数据(无页面) => 访问者
标准化返回:
{”code": 1001,"message": "参数不完整“,"data": {}/[]/other
}
*/

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

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

相关文章

Tomcat添加第三方jar包、如何在IDEA中启动部署Web模板

前言:公司最近维护老项目,是最原始的web项目,servlet和jsp结合的web项目,启动的时候配置了好几遍, 都起不来,很折磨人,这个文档比较全配置一遍准备工作 首先 拉取代码: git clone xxx.git ,如需要别的操作,自行baidu 也可以在idea中拉取第一步File ->Project Structure->…

Redis两种持久化方案RDB持久化和AOF持久化

Redis持久化 Redis有两种持久化方案&#xff1a; RDB持久化AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启…

VSCode插件Todo Tree的使用

在VSCode中安装插件Todo Tree。按下快捷键ctrlshiftP&#xff0c;输入setting.jspn&#xff0c;选择相应的配置范围&#xff0c;我们选择的是用户配置 Open User Settings(JSON)&#xff0c;将以下代码插入其中。 //todo-tree 标签配置从这里开始 标签兼容大小写字母(很好的功…

Spring Boot 集成Seata

Seata的集成方式有&#xff1a; 1. Seata-All 2. Seata-Spring-Boot-Starter 3. Spring-Cloud-Starter-Seata 本案例使用Seata-Spring-Boot-Starter演示&#xff1a; 第一步&#xff1a;下载Seata 第二步&#xff1a;为了更好看到效果&#xff0c;我们将Seata的数据存储改…

linuxARM裸机学习笔记(2)----汇编LED灯实验

MX6ULL 的 IO IO的复用功能 这里的只使用了低五位&#xff0c;用来配置io口&#xff0c;其中bit0~bit3(MUX_MODE)就是设置 GPIO1_IO00 的复用功能的&#xff0c;GPIO1_IO00 一共可以复用为 9种功能 IO&#xff0c;分别对应 ALT0~ALT8。每种对应了不同的功能 io的属性配置 HY…

SolidWorks 3D Interconnect介绍

目前市面上有的三维设计软件有很多&#xff0c;如UG、Pro/E、CATIA等&#xff0c;而且每个三维设计软件都会生成自己文件格式。由于产品设计的原因&#xff0c;我们避免不了的会需要去使用不同三维设计软件的文件&#xff0c;这对于工程师来说其实是一件比较麻烦的事。 为什么…

[腾讯云Cloud Studio实战训练营]基于Cloud Studio完成图书管理系统

[腾讯云Cloud Studio实战训练营]基于Cloud Studio完成图书管理系统 ⭐前言&#x1f31c;Cloud Studio产品介绍1.登录2.创建工作空间3.工作空间界面简介4.环境的使用 ⭐实验实操&#x1f31c;Cloud Studio实现图书管理系统1.实验目的 2. 实验过程2.实验环境3.源码讲解3.1添加数据…

下载Windows 10光盘镜像(ISO文件)

文章目录 下载Windows 10镜像文件 下载Windows 10镜像文件 打开微软官网下载地址 立即下载工具 找到下载工具&#xff0c;双击运行&#xff0c;等待 接受条款&#xff0c;等待 选择为另一台电脑安装介质 选择Windows10&#xff0c;下一步 选择ISO文件&#xff0c;…

【2023.8】docker一键部署wvp-GB28181-pro和ZLMediaKit过程全记录

安装docker 使用的操作系统是ubuntu20.04 如何在 Ubuntu 20.04 上安装和使用 Docker https://developer.aliyun.com/article/762674 docker拉取配置好的ZLMediaKIt和wvp-GB28181-pro docker pull 648540858/wvp_pro第一次运行 docker一键运行ZLMediaKIt和wvp-GB28181-pro …

spring boot中web容器配置

web容器配置 spring boot 默认的web容器是 tomcat&#xff0c;如果需要换成其他的 web 容器&#xff0c;可以如下配置。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 默…

使用 OpenCV 和 Python 卡通化图像-附源码

介绍 在本文中,我们将构建一个有趣的应用程序,它将卡通化提供给它的图像。为了构建这个卡通化器应用程序,我们将使用 python 和 OpenCV。这是机器学习令人兴奋的应用之一。在构建此应用程序时,我们还将了解如何使用 easygui、Tkinter 等库。在这里,您必须选择图像,然后应…

苍穹外卖day12(完结撒花)——工作台+Spring_Apche_POI+导出运营数据Excel报表

工作台——需求分析与设计 产品原型 接口设计 工作台——代码导入 将提供的代码导入对应的位置。 工作台——功能测试 Apache POI_介绍 应用场景 Apache POI_入门案例 导入坐标 <!-- poi --><dependency><groupId>org.apache.poi</groupId><ar…

《命运》阅读笔记

《命运》阅读笔记 2023年5月17号在杭州的小屋读完&#xff0c;我读完后&#xff0c;脑海里经常把余华的《活着》和这本《命运》的故事情节搞混淆&#xff0c;几乎都是讲着生活的苦难。全文以阿太&#xff08;外婆的妈妈&#xff09;的视角&#xff0c;在她九十九岁的人生里&…

《cuda c编程权威指南》05 - cuda矩阵求和

目录 1. 使用一个二维网格和二维块的矩阵加法 1.1 关键代码 1.2 完整代码 1.3 运行时间 2. 使用一维网格和一维块的矩阵加法 2.1 关键代码 2.2 完整代码 2.3 运行时间 3. 使用二维网格和一维块的矩阵矩阵加法 3.1 关键代码 3.2 完整代码 3.3 运行时间 1. 使用一个二…

记一次ubuntu16误删libc.so.6操作的恢复过程

背景 操作系统&#xff1a;ubuntu16 glibc版本&#xff1a;2.23 修改原因&#xff1a; 经过一系列报错和手工构建之后&#xff0c;vulkansdk成功安装&#xff08;起码运行./vulkansdu成功&#xff09;&#xff0c;在进行./vulkaninfo进行验证时&#xff0c;报错&#xff1a…

拦截器在SpringBoot中使用,HandlerInterceptor,WebMvcConfigurer

拦截器在Controller之前执行。 用于权限校验&#xff0c;日志记录&#xff0c;性能监控 在SpringBoot中使用 创建拦截器类&#xff1a;首先&#xff0c;创建一个Java类来实现拦截器逻辑。拦截器类应该实现Spring提供的HandlerInterceptor接口。实现拦截器方法&#xff1a;拦…

【Ubuntu】Ubuntu 22.04 升级 OpenSSH 9.3p2 修复CVE-2023-38408

升级原因 近日Openssh暴露出一个安全漏洞CVE-2023-38408&#xff0c;以下是相关资讯&#xff1a; 一、漏洞详情 OpenSSH是一个用于安全远程登录和文件传输的开源软件套件。它提供了一系列的客户端和服务器程序&#xff0c;包括 ssh、scp、sftp等&#xff0c;用于在网络上进行…

visual studio 生成dll文件以及修改输出dll文件名称操作

目录 visual studio 生成dll文件以及修改dll文件名称一、准备测试代码二、设置导出dll属性三、生成dll文件 .lib .dll .pdb 的简单介绍dll文件使用方式lib文件使用方式1、动态链接 &#xff08;原理&#xff09;2、静态链接&#xff1a; visual studio 生成dll文件以及修改dll文…

基于DiscordMidjourney API接口实现文生图

https://discord.com/api/v9/interactions 请求头&#xff1a; authorization:取自 浏览器中discord 文生图请求头中的 authorization 的值 Content-Type:application/json 请求体&#xff1a; {“type”:2,“application_id”:“93692956130267xxxx”,“guild_id”:“1135900…

Qt Creator中designer使用QWebEngine异常排查

Qt Creator中designer使用QWebEngine异常排查 1、前提背景 最近由于版权的原因&#xff0c;我们采取了自编译的Qt Creator。编译完成之后启动Qt Creator刚开始一切都是很顺利。 但是在Creator中打开designer&#xff0c;使用QWebEngine控件就发生了异常&#xff0c;Qt Creat…