go学习之接口知识

文章目录

    • 接口
      • 1.接口案例代码展示
      • 2.基本介绍
      • 3.基本语法
      • 4.应用场景介绍
      • 5.注意事项和细节
      • 6.接口编程经典案例
      • 7.接口与继承之间的比较
      • 8.面向对象编程--多态
        • 1)基本介绍
        • 2)快速入门
        • 3)接口体现多态的两种形式
      • 9.类型断言
        • 1)先看一个需求
        • 2)基本介绍
        • 3)类型断言的最佳实践1
        • 4)类型断言实践2

接口

1.接口案例代码展示

模拟通过支持usb接口的手机和相机开始工作

package main
import ("fmt"
)//声明定义一个接口
type Usb interface{Start()Stop()
}type Phone struct {}type Camera struct {}
//让phone实现usb接口的方法
func (p Phone) Start(){fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop(){fmt.Println("手机停止工作。。。")
}func (c Camera) Start(){fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop(){fmt.Println("相机停止工作。。。")
}
//计算机
type Computer struct{}//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口(所谓实现Usb接口,就是指实现了Usb接口声明所有方法)
func (c Computer) Working (usb Usb){//通过usb接口变量来调用Start和Stop方法usb.Start()usb.Stop()
}
func main(){//测试//先创建结构体变量computer :=Computer{}phone :=Phone{}camera := Camera{}//关键点computer.Working(phone)computer.Working(camera)}

2.基本介绍

interface类型可以定义一组方法,但是这些不需要实现。并且interface不能包含任何变量,到某个自定义类型(比如结构体Phone)要使用的时候,再根据具体情况把这些方法写出来

3.基本语法

type 接口名 interface{method1(参数列表)返回值列表method2(参数列表)返回值列表
}实现接口的方法
func (t 自定义类型)method1(参数列表)返回值列表{//方法实现
}
func (t 自定义类型)method2(参数列表)返回值列表{//方法实现
}

小结说明:

1)接口里的所有方法都没有方法体,即接口的方法都是没有实现的方法。接口体现了程序设计的多态和高内聚低耦合的思想。

2)Golang中的接口,不需要显式的实现。只要一个变量,含有接口类型中的所有方法,那么这个变量就实现这个接口。因此,Golang中没有implement这样的关键字

解释:假如有一个不同名字的接口,但是方法和原接口的方法一样,那么实现的方法也是实现了这个接口,golang中接口的实现不是基于名字而是基于方法。可以同时实现两个接口。

type Usb interface{Start()Stop()
}
type Usb2 interface{Start()Stop()
}

4.应用场景介绍

对初学者讲,理解接口不算太难,难的是不知道什么时候使用接口,下面几个例子来解释

1)现在美国要制造轰炸机,武装直升机,专家只需要把飞机需要的功能/规格定下来即可,然后让别人具体实现即可

2)就是做一个项目,在接口中定义规范让其他人去实现所定的规范

5.注意事项和细节

1)接口本身不能创建实例,但是可以指向一个实现了该接口的自定义类型的变量(实例)

package main
import ("fmt"
)type AInterface interface {Say()}type Stu struct {Name string
}
func (stu Stu)Say(){fmt.Println("Stu Say()")
}
func main(){var stu Stu  //结构体变量,实现了Say() 实现了AInterface这个接口var a AInterface =stua.Say() //Stu Say()
}

2)接口中所有的方法都没有方法体,即都是没有实现的方法

3)在Golang中,一个自定义类型需要将某个接口的所有方法都实现,我们说这个自定义类型实现了该接口

4)一个自定义类型只有实现了某个接口,才能将该自定义类型的实例(变量)赋给接口类型

5)只要是自定义数据类型,就可以实现接口,不仅仅是结构体类型(面试会问)

type integer int
type AInterface interface {Say()
}func (i integer)Say() {fmt.Println("integer Say i = ",i)
}
func main(){var i integer = 10var b AInterface = ib.Say() //integer Say i =  10
}

6)一个自定义类型可以实现多个接口

package main
import ("fmt"
)type AInterface interface {Say()}type Stu struct {Name string
}
func (stu Stu)Say(){fmt.Println("Stu Say()")
}type integer intfunc (i integer)Say() {fmt.Println("integer Say i = ",i)
}
type BInterface interface{Hello()
}
type Monster struct{}
func (m Monster) Hello(){fmt.Println("Monster Hello()~~")
}
func (m Monster) Say(){fmt.Println("Monster Say()~~")
}
//此时刻Monster就实现了AInterface和BInterfacefunc main(){var stu Stu  //结构体变量,实现了Say() 实现了AInterface这个接口var a AInterface =stua.Say() //Stu Say()var i integer = 10var b AInterface = ib.Say() //integer Say i =  10
//验证monster去实现两个接口var monster Monstervar a2 AInterface = monster //Monster Say()~~var b2 BInterface = monster //Monster Hello()~~a2.Say()b2.Hello()
}

7)Golang接口中不能有任何变量

例如,以下写法就是错误的
type AInteger interface {
Name string//这是错误的,不能这样用
test()
}

8)一个接口(比如A接口)可以继承多个别的接口(比如B,C接口),这时如果要实现A接口,也必须将B,C接口的方法也全部实现

package main
import ("fmt"
)
type BInterface interface {test01()
}
type CInterface interface {test02()
}
type AInterface interface {BInterfaceCInterfacetest03()
}
//如果需要实现AIerface,就需要把BInterface和CInterface的方法都实现
type Stu struct{}
//把所要实现的接口所有的方法都实现一下
func (stu Stu) test01(){fmt.Println("这是Test01")
}
func (stu Stu) test02(){fmt.Println("这是Test02")
}
func (stu Stu) test03(){fmt.Println("这是Test03")
}func main(){//实践var stu Stuvar a AInterface = stua.test01()a.test02()a.test03()
}

9)interface类型默认是一个指针(引用类型),如果没有对interface初始化就使用,那么就会输出nil

10)空接口interface{}没有任何方法,所以所有类型都实现了空接口

type T interface {}
func main(){//实践var stu Stuvar a AInterface = stua.test01()a.test02()a.test03()var t T =stufmt.Println(t)var t2 interface{} = stuvar num1 float64 = 8.8t2 = num1fmt.Println(t2,test02)
}

查看下列代码看看是否有错

type AInterface interface{Test01()Test02()
}
type BInterface interface{Test01()Test03()
}
type CInterface interface{AInterfaceBInterface
}
func main(){}
//这里编译错误,因为CInterface有两个test01().编译器不通过

来看第二个代码

type Usb interface{Say()
}
type Stu struct {}
func (this *Stu) Say() {
fmt,Println("Say()")
}func main() {
var stu Stu = Stu{}
//var u Usb =stu //会报错,因为stu没有实现Say()方法
var u Usb = &stu //改正之后,加个地址就可以了
u.Say()
fmt.Println("here",u)
}

6.接口编程经典案例

实现对hero结构体切片的排序:sort.Sort(data Interface)

package main
import ("fmt""sort""math/rand"
)//1.声明Hero结构体
type Hero struct {Name stringAge int
}//2.声明一个Hero的切片类型
type HeroSlice []Hero //3.实现Interface 接口
func (hs HeroSlice) Len() int {return len(hs )
}
//Less方法就是决定你是用什么标准进行排序
//1.按Hero的年龄从小到大进行排序!!
func (hs HeroSlice) Less(i,j int) bool {return hs[i].Age > hs[j].Age//修改成对姓名排序// return hs[i].Name > hs[j].Name
}func (hs HeroSlice) Swap(i,j int) {// temp := hs[i]// hs[i] =hs[j]// hs[j] = temp//简洁的交换:下面一句话等价于上面三句话hs[i],hs[j] = hs[j],hs[i]
}//声明一个Student结构体
//1.声明Student结构体
type Student struct {Name stringAge intScore int
}
//然后将上面那三个方法复制到下面//将student按成绩从大到小进行排序//声明一个Stu切片类型
type StuSlice []Student
//3.实现Interface 接口
func (stu StuSlice) Len() int {return len(stu)
}
//Less方法就是决定你是用什么标准进行排序
//1.按Hero的年龄从小到大进行排序!!
func (stu StuSlice) Less(i,j int) bool {//按成绩进行排序return stu[i].Score > stu[j].Score
}func (stu StuSlice) Swap(i,j int) {stu[i],stu[j] = stu[j],stu[i]
}func main(){//先定义一个数组/切片var intSlice = []int{0,-1,10,7,90}//要求对intSlice切片进行排序//1.冒泡排序...//2.可以使用系统提供的方法sort.Ints(intSlice)fmt.Println(intSlice)//[-1 0 7 10 90]//请对结构体进行排序//1.冒泡排序//2.系统提供的方法//测试我们是否可以对结构体进行排序var heroes HeroSlicefor i :=0;i < 10; i++{hero :=Hero {Name : fmt.Sprintf("英雄~%d",rand.Intn(100)),Age : rand.Intn(100),}//将hero append到heros切片heroes = append(heroes,hero)}//看看排序前的顺序for _, v := range heroes {fmt.Println(v)}fmt.Println( )//调用sort.Sort()sort.Sort(heroes)//看看排序后的顺序for _, v := range heroes {fmt.Println(v)}//这个接口的妙处就是将这个接口的三个方法实现然后只需要将结合挂钩梯放入到//sort方法中去就可以fmt.Println()var studentsl StuSlicefor i :=0;i < 10; i++{stus :=Student {Name : fmt.Sprintf("学生~%d",rand.Intn(100)),Age : rand.Intn(100),Score : rand.Intn(100),}//将hero append到heros切片studentsl = append(studentsl,stus)}//看看排序前的顺序for _, v := range studentsl {fmt.Println(v)}fmt.Println( )//调用sort.Sort()sort.Sort(studentsl)//看看排序后的顺序for _, v := range studentsl {fmt.Println(v)}
}

7.接口与继承之间的比较

1)大家可能对实现接口和继承比较迷茫了。那么问题来了,那么他们究竟有什么区别呢?

例如有一个猴子会爬树,然而他想学鸟儿飞翔,鱼儿游泳

package main
import ("fmt"
)
//,Monkey结构体
type Monkey struct {Name string
}//声明接口
type BirdAble interface {Flying()
}//声明接口
type FishAble interface {Swimming()
}
func (this *Monkey) climbing() {fmt.Println(this.Name,"生来会爬树")
}//创建LittleMonkey结构体
type LittleMonkey struct {Monkey //继承
}//让littleMonkey实现BirdAble的Flying()方法
func (this *LittleMonkey) Flying(){fmt.Println(this.Name,"通过学习会飞翔")
}
//littleMonkey实现FishAble的Swimming()方法
func (this *LittleMonkey) Swimming(){fmt.Println(this.Name,"通过学习会游泳")
}
func main(){//创建LittleMonkey实例monkey := LittleMonkey{Monkey {Name : "悟空",},}monkey.climbing()monkey.Flying()monkey.Swimming()}

对上面代码的小结

  1. 当A结构体继承了另外B结构体,那么A结构体就自动继承了B结构体的字段和方法,并且可以直接使用
  2. 当A结构体需要扩展功能,同时不希望去破坏继承关系,则可以去实现某个接口即可,因此我们可以认为:实现接口是对继承机制的补充。

实现接口可以看作是对继承的一种补充

在这里插入图片描述

  • 接口和继承解决的问题是不同的

继承的价值主要在于:解决代码的复用性可维护性

接口的价值主要在于:设计。设计好各种规范(方法),让其他自定义类型去实现这些方法

  • 接口比继承更加灵活 Person Student BirdAble LittleMonkey

  • 接口比继承更加灵活。继承是满足 is --a的关系。则接口只需满足like --a 的关系

  • 接口在一定程度上实现代码解耦

8.面向对象编程–多态

1)基本介绍

变量(实例)具有多种形态。面向对象的第三大特征,在Go语言,多态特征是通过接口实现的。可以按照统一的接口来调用不同的实现。这时接口变量就呈现不同的形态

2)快速入门

在前面的Usb接口案例:Usb usb 既可以接收手机变量,又可以接收相机变量,就体现了Usb接口多态特性。

//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口(所谓实现Usb接口,就是指实现了Usb接口声明所有方法)
func (c Computer) Working (usb Usb){//usb变量会根据传入的实参,来判断到底是Phone还是Camera//通过usb接口变量来调用Start和Stop方法usb.Start()usb.Stop()
}
func main(){//测试//先创建结构体变量computer :=Computer{}phone :=Phone{}camera := Camera{}//关键点computer.Working(phone)//传入phon就是phon执行这个方法computer.Working(camera)}
3)接口体现多态的两种形式

多态参数

在前面的Usb接口案例,Usb usb,既可以接收手机变量,又可以接收相机变量,就体现了Usb的接口多态

多态数组

演示一个案例给Usb数组,存放phone结构体和Camera结构体变量```go
package main
import ("fmt"
)//声明定义一个接口
type Usb interface{Start()Stop()
}type Phone struct {name string
}type Camera struct {name string
}
//让phone实现usb接口的方法
func (p Phone) Start(){fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop(){fmt.Println("手机停止工作。。。")
}func (c Camera) Start(){fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop(){fmt.Println("相机停止工作。。。")
}
//计算机
type Computer struct{}//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口(所谓实现Usb接口,就是指实现了Usb接口声明所有方法)
func (c Computer) Working (usb Usb){//通过usb接口变量来调用Start和Stop方法usb.Start()usb.Stop()
}
func main(){//定义一个Usb接口数组,可以存放Phone和Camera的结构体变量//这里就体现出多态数组var usbArr  [3]UsbusbArr[0] = Phone{"iphone"}usbArr[1] = Phone{"小米"}usbArr[2] = Camera{"佳能"}fmt.Println(usbArr) //[{iphone} {小米} {佳能}]}
```

9.类型断言

1)先看一个需求

代码

type Point struct{x inty int
}
func main() {var a interface{}var point Point = Pooint{1,2}a = point //OK//如何将A赋给一个Point变量?var b Pointb = a /可以吗? ==》errofmt.Println(b)
}
//改进之后
package main
import ("fmt"
)
type Point struct{x inty int
}
func main() {var a interface{}var point Point = Point{1,2}a = point //OK//如何将A赋给一个Point变量?var b Point//b = a //可以吗? ==》errob = a.(Point) //解决办法,类型断言//b = a.(Point)就是类型断言,表示判断a是否指向Poin类型的变量,如果是就转成了Point类型并赋给b变量,否则报错fmt.Println(b) //1 2
}

有一个具体的需要,引出了类型断言

2)基本介绍

类型断,由于接口是一般类型,不知道具体类型,如果要转成具体类型,就需要使用类型断言,具体的如下

//float32可以是其他类型,比如Point
var t float32
var x interface{}
x = t //OK
y := x.(float32)//转成float32//float32可以死其他类型,比如Point
var t float32 
var x interface{}
x = t
//转成float,待检查的
y,ok :=a.(float32)
if ok == true {
fmt.Println("convert success")
}else{
fmt.Println("convert fall")
}
/类型断言的其他案例var x interface{}var b2 float32 = 1.1x = b2 //空接口可以接收任意类型//x = >float32 【使用类型断言】y := x.(float32)fmt.Printf("y的类型是%T 值是%v",y,y) //y的类型是float32 值是1.1

对上面的代码的说明

在进行类型断言时,如果类型不匹配,就会报panic,因此进行类型断言时,要确保原来的空接口指向的就是断言的类型

如何在进行断言时带上检测机制,如果成功就ok否则也不要报panic

//类型断言(带检测)
var x interface{}
var b2 float32 = 1.1
x = b2 //空接口可以接收任意类型
//x = >float32 【使用类型断言】
//y,ok := x.(float64)
//简写if  y,ok := x.(float64);ok {fmt.Println("转换成功了")fmt.Printf("y的类型是%T 值是%v",y,y) //y的类型是float32 值是1.1
}else{fmt.Println("转换失败")
}
fmt.Println("检测失败了无妨,代码不要停")}
3)类型断言的最佳实践1

在前面的Usb接口案例做改进

给Phone结构体增加一个特有的方法call(),当Usb接口接收的是Phone变量时,还需要调用call方法。

package main
import ("fmt"
)//声明定义一个接口
type Usb interface{Start()Stop()
}type Phone struct {name string
}type Camera struct {name string
}
//让phone实现usb接口的方法
func (p Phone) Start(){fmt.Println("手机开始工作。。。")
}
func (p Phone) Stop(){fmt.Println("手机停止工作。。。")
}func (p Phone) Call(){fmt.Println("手机开始打电话。。。")
}func (c Camera) Start(){fmt.Println("相机开始工作。。。")
}
func (c Camera) Stop(){fmt.Println("相机停止工作。。。")
}
//计算机
type Computer struct{}//编写一个方法Working方法,接收一个Usb接口类型变量
//只要是实现了Usb接口(所谓实现Usb接口,就是指实现了Usb接口声明所有方法)
func (c Computer) Working (usb Usb){//通过usb接口变量来调用Start和Stop方法usb.Start()//如果usb是指向Phone结构体变量,则还需要调用Call()方法//类型断言if phone, ok := usb.(Phone); ok {phone.Call()}//否则断言失败还是继续执行下列方法usb.Stop()
}func main(){//定义一个Usb接口数组,可以存放Phone和Camera的结构体变量//这里就体现出多态数组var usbArr  [3]UsbusbArr[0] = Phone{"iphone"}usbArr[1] = Phone{"小米"}usbArr[2] = Camera{"佳能"}//fmt.Println(usbArr) //[{iphone} {小米} {佳能}]//遍历var computer Computerfor _,v := range usbArr{computer.Working(v)fmt.Println()}}
执行结果如下:
手机开始工作。。。
手机开始打电话。。。
手机停止工作。。。手机开始工作。。。
手机开始打电话。。。
手机停止工作。。。相机开始工作。。。
相机停止工作。。。
4)类型断言实践2

写一个函数,循环判断传入参数的类型

package main
import ("fmt"
)
//编写一个函数,可以判断输入的参数是什么类型
func TypeJudge(items... interface{}){for index, x := range items {switch x.(type) {case bool : fmt.Printf("第%v个参数是 bool 类型,值是%v\n",index+1,x)case float32 : fmt.Printf("第%v个参数是 float32 类型,值是%v\n",index+1,x)case float64 : fmt.Printf("第%v个参数是 float64 类型,值是%v\n",index+1,x)	case int, int32, int64 : fmt.Printf("第%v个参数是 整数 类型,值是%v\n",index+1,x)		  	  case string : fmt.Printf("第%v个参数是 string 类型,值是%v\n",index+1,x)default :fmt.Printf("第%v个参数是 类型 不确定,值是%v\n",index+1,x)	}}}
func main(){var n1 float32 = 1.1var n2 float64 = 2.3var n3 int32 = 30var name = "tom"address := "北京"n4 :=300TypeJudge(n1,n2,n3,name,address,n4)}
//运行结果如下1个参数是 float32 类型,值是1.12个参数是 float64 类型,值是2.33个参数是 整数 类型,值是304个参数是 string 类型,值是tom
第5个参数是 string 类型,值是北京
第6个参数是 整数 类型,值是300

5)类型断言的最佳实践3

在前面代码的基础上,增加判断Student类型和*Student类型

package main
import ("fmt"
)//定义Student类型
type Student struct {}
//编写一个函数,可以判断输入的参数是什么类型
func TypeJudge(items... interface{}){for index, x := range items {switch x.(type) {case bool : fmt.Printf("第%v个参数是 bool 类型,值是%v\n",index+1,x)case float32 : fmt.Printf("第%v个参数是 float32 类型,值是%v\n",index+1,x)case float64 : fmt.Printf("第%v个参数是 float64 类型,值是%v\n",index+1,x)	case int, int32, int64 : fmt.Printf("第%v个参数是 整数 类型,值是%v\n",index+1,x)		  	  case Student : fmt.Printf("第%v个参数是 Student 类型,值是%v\n",index+1,x)case *Student : fmt.Printf("第%v个参数是 *Student 类型,值是%v\n",index+1,x)case string : fmt.Printf("第%v个参数是 string 类型,值是%v\n",index+1,x)default :fmt.Printf("第%v个参数是 类型 不确定,值是%v\n",index+1,x)	}}}func main(){var n1 float32 = 1.1var n2 float64 = 2.3var n3 int32 = 30var name = "tom"address := "北京"n4 :=300stu1 := Student{}stu2 := &Student{}TypeJudge(n1,n2,n3,name,address,n4,stu1,stu2)}

数是什么类型
func TypeJudge(items… interface{}){
for index, x := range items {
switch x.(type) {
case bool :
fmt.Printf(“第%v个参数是 bool 类型,值是%v\n”,index+1,x)
case float32 :
fmt.Printf(“第%v个参数是 float32 类型,值是%v\n”,index+1,x)
case float64 :
fmt.Printf(“第%v个参数是 float64 类型,值是%v\n”,index+1,x)
case int, int32, int64 :
fmt.Printf(“第%v个参数是 整数 类型,值是%v\n”,index+1,x)
case Student :
fmt.Printf(“第%v个参数是 Student 类型,值是%v\n”,index+1,x)
case *Student :
fmt.Printf(“第%v个参数是 *Student 类型,值是%v\n”,index+1,x)
case string :
fmt.Printf(“第%v个参数是 string 类型,值是%v\n”,index+1,x)

		default :fmt.Printf("第%v个参数是 类型 不确定,值是%v\n",index+1,x)	}
}

}

func main(){
var n1 float32 = 1.1
var n2 float64 = 2.3
var n3 int32 = 30
var name = “tom”
address := “北京”
n4 :=300

stu1 := Student{}
stu2 := &Student{}TypeJudge(n1,n2,n3,name,address,n4,stu1,stu2)

}


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

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

相关文章

登顶request模块

华子目录 Requests介绍安装requests模块常用方法常用属性实例引入各种请求方式基于get请求带参数的get请求推荐写法 基于post请求添加headers信息content获取二进制数据bytes类型获取json数据第一种方式第二种方式 response响应状态码判断 高级操作会话维持通过cookie维持会话通…

【Vue3】scoped 和样式穿透

我们使用很多 vue 的组件库&#xff08;element-plus、vant&#xff09;&#xff0c;在修改样式的时候需要进行其他操作才能成功更改样式&#xff0c;此时就用到了样式穿透。 而不能正常更改样式的原因就是 scoped 标记。 scoped 的渲染规则&#xff1a; <template>&l…

U-Mail邮件中继,让海外邮件沟通更顺畅

在海外&#xff0c;电子邮件是人们主要的通信工具&#xff0c;尤其是商务往来沟通&#xff0c;企业邮箱是标配。这主要是因为西方国家互联网发展较早&#xff0c;在互联网早期&#xff0c;电子邮件技术较为成熟&#xff0c;大家都用电子邮件交流&#xff0c;于是这成了一种潮流…

Android 基本属性绘制文本对象FontMetrics

FontMetrics对象 它以四个基本坐标为基准&#xff0c;分别为&#xff1a; ・FontMetrics.top ・FontMetrics.ascent ・FontMetrics.descent ・FontMetrics.bottom 如图: 要点如下&#xff1a; 1. 基准点是baseline 2. Ascent是baseline之上至字符最高处的距离 3. Descent是ba…

RT-Thread:嵌入式实时操作系统的设计与应用

RT-Thread&#xff08;Real-Time Thread&#xff09;是一个开源的嵌入式实时操作系统&#xff0c;其设计和应用在嵌入式领域具有重要意义。本文将从RT-Thread的设计理念、核心特性&#xff0c;以及在嵌入式系统中的应用等方面进行探讨&#xff0c;对其进行全面的介绍。 首先&a…

SMART PLC MODBUSTCP速度测试

SMART PLC MODBUSTCP通信详细介绍请参看下面文章链接: S7-200SMART PLC ModbusTCP通信(多服务器多从站轮询)_matlab sumilink 多个modbustcp读写_RXXW_Dor的博客-CSDN博客文章浏览阅读6.4k次,点赞5次,收藏10次。MBUS_CLIENT作为MODBUS TCP客户端通过S7-200 SMART CPU上的…

数据结构—二叉树的模拟实现(c语言)

目录 一.前言 二.模拟实现链式结构的二叉树 2.1二叉树的底层结构 2.2通过前序遍历的数组"ABD##E#H##CF##G##"构建二叉树 2.3二叉树的销毁 2.4二叉树查找值为x的节点 2.5二叉树节点个数 2.6二叉树叶子节点个数 2.7二叉树第k层节点个数 三.二叉树的遍历 3.1…

ConstraintLayout的基本用法

ConstraintLayout的基本用法 1、基线对齐——Baseline 有时候我们需要这样一个场景&#xff1a; app:layout_constraintBaseline_toBaselineOf"id/30"2、链——Chains 用于将多个控件形成一条链&#xff0c;可以用于平分空间。 <?xml version"1.0"…

【Bug】当用opencv库的imread()函数读取图像,用matplotlib库的plt.imshow()函数显示图像时,图像色彩出现偏差问题的解决方法

一&#xff0c;问题描述 我们在利用opencv的imread读取本地图像&#xff0c;进行一系列处理&#xff0c;但是发现用matplotlib库的imshow&#xff08;&#xff09;函数显示的时候出现色彩改变&#xff0c;比如图像偏黄&#xff0c;偏红&#xff0c;偏蓝等等&#xff0c;但是对…

2023年第十六届山东省职业院校技能大赛中职组“网络安全”赛项规程

第十六届山东省职业院校技能大赛 中职组“网络安全”赛项规程 一、赛项名称 赛项名称&#xff1a;网络安全 英文名称&#xff1a;Cyber Security 赛项组别&#xff1a;中职组 专业大类&#xff1a;电子与信息大类 二、竞赛目的 网络空间已经成为陆、海、空、天之后的第…

AI 时代的企业级安全合规策略

目录 漏洞分类管理的流程 安全策略管理 在扫描结果策略中定义细粒度的规则 有效考虑整个组织中的关键漏洞 确保职责分离 尝试组合拳 本文来源&#xff1a;about.gitlab.com 作者&#xff1a;Grant Hickman 在应用程序敏捷研发、敏捷交付的今天&#xff0c;让安全人员跟上…

神经网络(第二周)

一、简介 1.1 需求预测示例 1.1.1 逻辑回归算法 根据价格预测商品是否畅销。特征&#xff1a;T恤的价格&#xff1b;分类&#xff1a;销售量高1/销售量低0&#xff1b;使用逻辑回归算法进行分类&#xff0c;拟合效果如下图所示&#xff1a; 1.1.2 神经元和神经网络 将逻辑回…

Module build failed (from ./node_modules/postcss-loader/src/index.js):

出现该错误是你可能没认真看官网的安装配置&#xff0c;可直接看该目录3&#xff0c;一个字一个字看 先安装uview 如果选择v1版本&#xff0c;建议使用npm下载&#xff0c;下面以v1版本为例&#xff0c;使用的是npm下载&#xff0c;导入uview时该文件也在node_modules文件夹里…

Anolis 8.6 安装 Drawio

Anolis 8.6 安装 Drawio 22.1.0 一.RPM版&#xff08;不建议&#xff09;二.WAR 包部署 一.RPM版&#xff08;不建议&#xff09; Draw RPM 包下载链接 RPM 包直接基于Linux图形化能力部署&#xff0c;服务器类型的Linux系统启动RPM包安装的Draw可能比较复杂 系统版本 ## 1.…

(一)正点原子I.MX6ULL kernel6.1移植准备

一、概述 学完了正点原子的I.MX6ULL移植&#xff0c;正点原子的教程是基于Ubuntu18&#xff0c;使用的是4.1.15的内核&#xff0c;很多年前的了。NXP官方也发布了新的6.1的内核&#xff0c;以及2022.04的uboot。 本文分享一下基于Ubuntu22.04&#xff08;6.2.0-36-generic&…

Unity中Shader的雾效

文章目录 前言一、Unity中的雾效在哪开启二、Unity中不同种类雾的区别1、线性雾2、指数雾1&#xff08;推荐用这个&#xff0c;兼具效果和性能&#xff09;3、指数雾2&#xff08;效果更真实&#xff0c;性能消耗多&#xff09; 三、在我们自己的Shader中实现判断&#xff0c;是…

【c++随笔12】继承

【c随笔12】继承 一、继承1、继承的概念2、3种继承方式3、父类和子类对象赋值转换4、继承中的作用域——隐藏5、继承与友元6、继承与静态成员 二、继承和子类默认成员函数1、子类构造函数 二、子类拷贝构造函数3、子类的赋值重载4、子类析构函数 三、单继承、多继承、菱形继承1…

设计模式-工厂方法

工厂方法是一种创建型设计模式&#xff0c;其在父类中提供一个创建对象的方法&#xff0c;允许子类决定实例化对象的类型。 问题 假设你开设了一个汽车工厂。创业初期工厂只能生产宝马这一款车&#xff0c;因此大部分代码都位于名为宝马的类中。 工厂效益非常好&#xff0c;为…

IDEA搭建ssm项目

此前&#xff0c;我一直在用eclipse编辑器做java项目&#xff0c;现在初次使用IDEA编辑器&#xff0c;在这里&#xff0c;我记录了使用IDEA环境下搭建ssm项目的过程。 创建Maven项目&#xff0c;如下 右击TEST4项目&#xff0c;在弹出的菜单中选择Add Framework Support 在弹出…

屏幕提词软件Presentation Prompter mac中文版使用方法

Presentation Prompter for mac是一款屏幕提词器软件&#xff0c;它可以将您的Mac电脑快速变成提词器&#xff0c;支持编写或导入&#xff0c;可以在一个或多个屏幕上平滑地滚动&#xff0c;Presentation Prompter 下载是为适用于现场表演者&#xff0c;新闻广播员&#xff0c;…