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 =stu
   a.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 = 10
   var b AInterface = i
   b.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 int

func (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和BInterface

func main(){
   var stu Stu  //结构体变量,实现了Say() 实现了AInterface这个接口
   var a AInterface =stu
   a.Say() //Stu Say()
   var i integer = 10
   var b AInterface = i
   b.Say() //integer Say i =  10
//验证monster去实现两个接口
   var monster Monster
   var 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 {
	BInterface
	CInterface
	test03()
}
//如果需要实现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 Stu
	var a AInterface = stu
	a.test01()
	a.test02()
	a.test03()
}

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

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

type T interface {

}
func main(){
    //实践
	var stu Stu
	var a AInterface = stu
	a.test01()
	a.test02()
	a.test03()
	var t T =stu
	fmt.Println(t)
	var t2 interface{} = stu
	var num1 float64 = 8.8
	t2 = num1
	fmt.Println(t2,test02)
}

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

type AInterface interface{
   Test01()
   Test02()
}
type BInterface interface{
   Test01()
   Test03()
}
type CInterface interface{
   AInterface
   BInterface
}
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 string
	Age 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 string
	Age int
	Score 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 HeroSlice
	for 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 StuSlice
	for 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]Usb
   usbArr[0] = Phone{"iphone"}
   usbArr[1] = Phone{"小米"}
   usbArr[2] = Camera{"佳能"}
   fmt.Println(usbArr) //[{iphone} {小米} {佳能}]
	
}
```




9.类型断言

1)先看一个需求

代码

type Point struct{
     x int
     y int
}
func main() {
    var a interface{}
    var point Point = Pooint{1,2}
    a = point //OK
    //如何将A赋给一个Point变量?
    var b Point
    b = a /可以吗? ==》erro
    fmt.Println(b)
}
//改进之后
package main
import (
	"fmt"
)
type Point struct{
	x int
	y int
}
func main() {
   var a interface{}
   var point Point = Point{1,2}
   a = point //OK
   //如何将A赋给一个Point变量?
   var b Point
   //b = a //可以吗? ==》erro
   b = 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.1
   x = 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]Usb
   usbArr[0] = Phone{"iphone"}
   usbArr[1] = Phone{"小米"}
   usbArr[2] = Camera{"佳能"}
   //fmt.Println(usbArr) //[{iphone} {小米} {佳能}]
   //遍历
   var computer Computer
   for _,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.1
	var n2 float64 = 2.3
	var n3 int32 = 30
	var name = "tom"
	address := "北京"
	n4 :=300
    
	TypeJudge(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.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)

}

数是什么类型
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)

}


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【第六章】软件设计师 之 数据结构与算法基础

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 1、数据结构与算法基础 2、数据 3、稀疏矩阵…

分享一下关于“vcruntime140_1.dll丢失的5种解决方法

今天我来给大家分享一下关于“vcruntime140_1.dll丢失的5种修复方法”的分享。首先&#xff0c;我们来了解一下vcruntime140_1.dll丢失的原因。 病毒感染&#xff1a;病毒或恶意软件可能损坏或删除vcruntime140_1.dll文件。 系统更新或软件安装&#xff1a;在进行系统更新或安…

每日一练:使用Python计算从m到n的累加和

设计思路 可以定义一个函数来计算从m到n的整数累加和&#xff0c;这个函数会接受两个参数&#xff1a;m和n&#xff0c;然后通过使用for循环和range函数&#xff0c;遍历从m到n&#xff08;包括n&#xff09;的所有整数&#xff0c;并将它们加起来。 代码实现 def sum_of_nu…

链表的实现(文末附完整代码)

链表的概念及结构 链表是一种物理存储结构上非连续、非顺序的存储结构&#xff0c;数据元素的逻辑顺序是通过链表中的指针链接次序实现的 我们在上一篇文章所学习的顺序表是连续存储的 例如&#xff1a; 顺序表就好比火车上的一排座位&#xff0c;是连续的 而链表就好比是火车…

LabVIEW中如何在网络上使用远程VI服务器

LabVIEW中如何在网络上使用远程VI服务器 如何在网络上使用远程VI服务器&#xff1f; 解答: 首先&#xff0c;需要在远程的计算机上打开一个在VI服务器上的LabVIEW应用程序的引用。这可以通过“Open ApplicationReference“函数实现。然后用“Open VI Reference”函数打开一个…

VulnHub Prime_Series_Level-1

一、信息收集 1.nmap扫描 ┌──(root&#x1f480;kali)-[~/桌面] └─# arp-scan -l┌──(root&#x1f480;kali)-[~/桌面] └─# nmap -sS -A -p- 192.168.103.202发现开放了22和80端口 2.web页面 打开80端口的web页面&#xff0c;是一张静态的图片&#xff0c;没什么价…

Linux文件系统(1)

Linux文件系统(1) &#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;Linux &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 本博客主要内容从系统层面重新认识我们的文件系统 文…

java的类和继承构造

一些小技巧 类和对象 什么是类&#xff0c;对象&#xff0c;方法&#xff1f; 在下面的 Java 代码中&#xff0c;定义了一个名为 Person 的类&#xff0c;并提供了构造方法来初始化对象的属性。类中定义了 eat、sleep 和 work 三个方法&#xff0c;用于表示人的行为。在 main 方…

为什么Android 手机这么慢?如何提高 Android 手机的运行速度

速印机&#xff08;理想、荣大等&#xff09;、复印机&#xff08;夏普、东芝、理光、佳能、震旦等全系列&#xff09;、打印机、扫描仪、传真机、多媒体教学一体机、交互式电子白板、报警器材、监控、竞业达监考设备及其它监考设备、听力考试设备、特种安防设备维护及维修。吴…

JavaScript_动态表格_添加功能

1、动态表格_添加功能.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>动态表格_添加功能</title><style>table{border: 1px solid;margin: auto;width: 100%;}td,th{text-align: ce…

Django 基于ORM的CURD、外键关联,请求的生命周期

文章目录 基于ORM进行的CURDORM外键关联Django请求的生命周期流程图 基于ORM进行的CURD 本质上就是通过面向对象的方式&#xff0c;对数据库的数据进行增、删、改、查。 这里将会将我们之前所有内容结合到一起&#xff0c;首先确保基于上序操作已经建立好了UserInfo表&#xff…

odoo16 库存初始化 excel导入问题2

产品导入模板: excel内容: 导入测试 查看可能的值,发现没有ml,在计量单位中增加ml选项(不选创建,知道为什么不,仔细想想,创建不知ml是什么单位) 位置不能在此导入,故取消 测试正常 导入成功 总结:产品导入时,位置无法指定,只建产品名称,计量单位,采购单位,

自定义Graph Component:1.1-JiebaTokenizer具体实现

JiebaTokenizer类继承自Tokenizer类&#xff0c;而Tokenizer类又继承自GraphComponent类&#xff0c;GraphComponent类继承自ABC类&#xff08;抽象基类&#xff09;。本文使用《使用ResponseSelector实现校园招聘FAQ机器人》中的例子&#xff0c;主要详解介绍JiebaTokenizer类…

python工具CISCO ASA设备任意文件读取

​python漏洞利用 构造payload&#xff1a; /CSCOT/translation-table?typemst&textdomain/%2bCSCOE%2b/portal_inc.lua&default-language&lang../漏洞证明&#xff1a; 文笔生疏&#xff0c;措辞浅薄&#xff0c;望各位大佬不吝赐教&#xff0c;万分感谢。 免…

golang Copier 数据复制

Copier I am a copier, I copy everything from one to another Copier是golang实现的&#xff0c;实现不同数据结构之间数据复制的工具包 github地址 使用方法 以User和Employee之间相互复制为例 使用的版本为 v0.3.5 入门 package mainimport ("fmt""git…

DevChat 初探之 RBAC 模型的实现

今天我们来尝试一款编程辅助助手 DevChat, 看能不能提升咱们的日常编程效率。作为一款编程助手&#xff0c;我们来看看它与 Copilot, CodeWhisperer 同领域产品的一些区别和特色。定个小目标&#xff0c;通过 DevChat 实现一个简单的 RBAC 模型&#xff0c;小试牛刀一下&#x…

Acer宏碁Aspire A715-75G笔记本工厂模式原厂Windows10预装OEM系统2004带恢复功能

下载链接&#xff1a;https://pan.baidu.com/s/1nJFd25lElc1VAPf_RqSDYA?pwdd05h 提取码&#xff1a;d05h 原装出厂系统自带所有驱动、Office办公软件、出厂主题壁纸、系统属性Acer宏基专属的LOGO标志、 Acer Care Center、Quick Access等预装程序 所需要工具&#xff1a…

kubenetes-kubelet组件

一、kubelet架构 每个节点都运行一个kubelet进程&#xff0c;默认监听10250端口&#xff0c;kubelet作用非常重要&#xff0c;是节点的守护神。 接收并执行 master发来的指令。管理Pod及Pod中的容器。每个kubelet进程会在API Server 上注册节点自身信息&#xff0c;定期向mast…

mysql讲解2 之事务 索引 以及权限等

系列文章目录 mysql 讲解一 博客链接 点击此处即可 文章目录 系列文章目录一、事务1.1 事务的四个原则1.2 脏读 不可重复读 幻读 二、索引三,数据库用户管理四、mysql备份 一、事务 1.1 事务的四个原则 什么是事务 事务就是将一组SQL语句放在同一批次内去执行 如果一个SQ…