go的结构体、方法、接口

结构体:

结构体:不同类型数据集合
结构体成员是由一系列的成员变量构成,这些成员变量也被称为“字段”

先声明一下我们的结构体:

type Person struct {name stringage  intsex  string
}

定义结构体法1:

var p1 Personfmt.Println(p1)p1.name = "XUPT"p1.sex = "无性别"p1.age = 74

定义结构体法2:

p2 := Person{}p2.age = 244p2.name = "艾美莉卡"p2.sex = "沃尔玛购物袋"fmt.Println(p2) //{艾美莉卡 244 沃尔玛购物袋}

定义结构体法3:

	p3 := Person{name: "荷叶饭",sex: "女",age: 18, //加逗号}fmt.Println(p3) //{荷叶饭 18 女}

定义结构体法4:

p4 := Person{"米库",16,"女",}fmt.Println(p4) //{米库 16 女}

结构体为值类型,默认深拷贝(连同对象引用的所有嵌套对象(或指针指向的对象)都进行独立的复制),往往用指针操纵:

    fmt.Printf("%T\n", &p4) //*main.Personfmt.Printf("%T\n", p1)  //main.Person

当你对一个结构体变量取地址时,返回的是这个结构体在内存中的存储位置,这个“储存位置”就是用指针类型来储存的

定义结构体指针:

var pp1 *Personpp1 = &p1//p1是一个结构体,对p1取地址就是一个指针,所以可以画等号fmt.Println(pp1)fmt.Printf("%p,%T\n", pp1, pp1) //0xc0001040c0,*main.Personfmt.Println(*pp1)               //{XUPT 74 无性别}

使用内置函数new(),go中专门用来创建某种类型的指针的函数

    pp2 := new(Person)fmt.Printf("%p,%T\n", pp2, pp2) //0xc0000202d0,*main.Person,指针类型(*pp2).name = "zyzy"//也可以省略前面的*号,pp2.name="tzz"(*pp2).age = 22(*pp2).sex = "男"fmt.Println(pp2) //&{zyzy 22 男}

创建匿名结构体,一个没有名称的结构体:

s2 := struct {name stringage  int}{name: "无敌高考大王",age:  18,}fmt.Println(s2.name, s2.age)

好处:

简洁性

  • 代码简洁:匿名结构体允许我们在定义变量的同时声明其类型,这减少了代码量并提高了可读性。
  • 减少命名负担:对于只使用一次的小型结构体,无需费心命名。

灵活性

  • 即时定义:在函数或方法中快速定义新的数据结构,非常适合处理一次性的、结构简单的数据。

结构体允许其成员字段在声明时没有字段名而只有类型,这种没有名字的字段就称为匿名字段。

type Worker struct {/*name stringage  int*/stringint //匿名字段
}

定义一个含匿名字段的结构体:

w2 := Worker{"无敌崩坏星穹铁道大王",18,}fmt.Println(w2.string, w2.int) //打印匿名字段结构体

嵌套结构体:

结构体里套着结构体:

type Book struct {bookName stringprice    float64
}
type Studentbook struct {name stringage  intbook Book
}

定义法1:

​
ss2 := Studentbook{name: "code",age:  18,book: Book{"西西弗神话",24.9,},}fmt.Println(ss2)​

定义法2:

	bb1 := Book{}bb1.bookName = "1984"bb1.price = 45.8ss1 := Studentbook{}ss1.name = "奥威尔"ss1.age = 24ss1.book = bb1fmt.Println(bb1)fmt.Println(ss1)

定义法3:

bb3 := Book{bookName: "三体",price:    14.9,}ss3 := Studentbook2{name: "刘慈欣",age:  18,book: &bb3,}fmt.Println(bb3)                               //{三体 14.9}fmt.Println(ss3)          

type关键字

1.类型定义:type 类型名 Type
2.类型别名:type 类型名=Type

    var i1 myint        //intvar i2 = 100        //intvar str1 mystrstr1 = "嘻嘻"
//main函数外
type myint int
type mystr string

看上去好像myint和int没什么区别?

打印一下他们的数据类型:

fmt.Printf("i1类型==%T\ni2类型==%T\n", i1, i2)//i2!=i1,i1,i2是两种语法类型
fmt.Printf("str1类型==%T\n", str1) //main.mystr

所以他们不是同一种数据类型,不能直接相等哦

我们也可以用type来重命名我们的函数类型:

type myfun func(int, int) string//定义一个新的函数类型,myfun就等价于 func(int,int)string
//照这个类型定义一个函数,等价于 func fun11() func(int, int) string
func fun11() myfun {fun := func(a, b int) string {s := strconv.Itoa(a) + strconv.Itoa(b)return s}return fun
}
/*
上述函数等价于
func fun11() func(int, int) string {fun := func(a, b int) string {s := strconv.Itoa(a) + strconv.Itoa(b)return s}return fun
}*/

调用我们的函数:

​res1 := fun11()fmt.Println(res1(10, 20)) //拼接10和20type myint2 = int         //给int起了别名,就像define

放弃了大量面向对象的特性,首字母大写可共用,小写为私用

这个类的私用和共用和保护在c++中是这么体现的:

class BaseClass {
public:// 公有成员int publicData;protected:// 保护成员int protectedData;
};class DerivedClass : public BaseClass {
public:// 在派生类中可以访问基类的保护成员void accessProtected() {protectedData = 42; // 正常访问}private:// 派生类有自己的私有成员int derivedPrivate;
};int main() {DerivedClass d;d.publicData = 10; // 可见,因为是公有的d.accessProtected(); // 可见,因为DerivedClass继承了BaseClass// BaseClass的对象尝试访问protectedData是不允许的// BaseClass base;// base.protectedData = 50; // 错误,protectedData仅对DerivedClass可见return 0;
}

如果我们写成go应该是这样的:        

package mainimport "fmt"type BaseClass struct {PublicData  int //共有字段protectData int //protected,只能在包内私用,未导出的字段
}// 模拟c++的继承,嵌套结构体
type DerivedClass struct {BaseClassderivedPrivate int
}func (d *DerivedClass) AccessProtected() {d.protectData = 42 //访问我们未导出的protected字段fmt.Println("protectData==", d.protectData)
}
func main() {d := DerivedClass{}d.PublicData = 10fmt.Println("d.PublicData==", d.PublicData)d.AccessProtected()base := BaseClass{}base.protectData = 50 // 如果在c++里编译错误:无法访问,因为我们的protected是对于派生类可以被访问//但是在go里,我们不能把protected限定在类里,只能控制它在包内和包外是否可调用fmt.Println(base.protectData) //50fmt.Println("program finished")
}

很显然我们的go在面向对象这方面并不能像c++一样(比如我们的protected类)

oop(面向对象)

面向对象和面向过程的区别:

其实不止操作系统,很多系统的管理模式都是用面向对象的模式管理的

管理者并不在乎你每个人的个体特征。

在公司里,老板让你买咖啡,并且他很急。买咖啡有多种方式,例如点外卖、自己到楼下购买、托正在外面的同事捎来或者给老板花超绝三块钱冲雀巢等等。然后你就问老板说:老板,那我是去点外卖还是自己买还是给你冲速溶咖啡还是......老板根本不在乎你说的什么,他只会告诉你:不管怎样,我只要我的桌子上放有咖啡。

员工只要搞到咖啡就好了,而老板考虑的就多了(勾潮的鸣式还在追我

老板这个命令就叫面向对象(oop)他不在乎事情处理的过程;底层员工要做的就是处理好这些事情的过程。

面向对象就是把拥有复杂过程的事情抽象为一个类,比如在这里我们把自己买咖啡、点外卖、冲咖啡这种事情全部抽象为搞到咖啡(其实很像那些不近人情的上级会说:我不问过程只要结果呃呃)

本质上获得咖啡的途径,就是面向过程(opp)。也就是说,面向对象的最底层的实现方法还是面向过程。只不过在这里,面向过程被我们抽象为一个类。

按C++的STL来举例子:首先我们需要一个工具箱,里面装着我们需要的东西。于是我们先创造了工具箱这个东西;然后我们就要想在我们的工具箱里塞什么东西,比如说我需要一个排序的函数,需要一个求大值、最小值的函数;然后我们再去编写函数里面的内容,这个函数最里面的内容是面向过程,然后外边整体用的是面向对象的思想。

也就是说对特定对象先描述,再组织
————————————————

之前写的部分          
原文链接:https://blog.csdn.net/Au_ust/article/details/141108377 

对象是最基本的单位,例如switch就是一个对象,描述他的有属性(是个程序员)和方法(打炉石传说)

这种类型的人可以被抽象、概括出来,就是一个类,例如上述的像switch一样的人可以被抽象为爱打炉石传说的程序员,像她一样爱打炉石传说的程序员都在这个类里面

 面向对象编程具有三大特性:封装、继承、多态

封装:将对象的属性和方法打包

继承:子类可以继承父类已有的功能

多态:不同的类执行不同的方法有不同的结果

在go语言中其实并不具有一种完备的面向对象的机制,没有什么内联函数,不如c++

但是我们可以使用偷感很重的方式:用接口和方法模拟oop的特性:

 1.模拟继承性:is-a(是),一个类继承一个类
                    子类可以直接访问父类的属性和方法
                    子类可以新增自己的属性和方法
                    子类可以重写父类的方法(override,就是将父类已有的方法,重新实现)

type A struct{
field
}
type B struct{
A//匿名字段
//可以在B的里面,在A的基础上修改A的方法属性
}

2.模拟聚合关系 has-a(有),一个类拥有一个类

//这个很好理解
type C struct{field
}
type D struct{c C//聚合关系
}

3.模拟多态
一个对象受到类型的限制,可以定义为父类类型,也可以定义为子类,类似于界门纲目科属种的关系
类型不同,能够访问的字段(功能)不同
go语言通过接口模拟多态,就是一个接口的实现
       1.看成实现本身的类型,能够访问实现类中的属性和方法
       2.看成是对应接口的类型,只能访问接口中定义的方法

一个很弱智很普通的模拟面向对象的实现:

package mainimport "fmt"func main() {//1.创建父类对象p1 := Personoop{"张三", 18}fmt.Println(p1)fmt.Println(p1.name, p1.age)//2.创建子类对象s1 := Studentoop{Personoop{"李四", 18}, "XUPT"}fmt.Println(s1)s2 := Studentoop{Personoop: Personoop{"王五", 18}, school: "XUPT"}fmt.Println(s2)var s3 Studentoops3.Personoop.name = "老公"s3.Personoop.age = 18s3.school = "CCUT"fmt.Println(s3) //{{老公 18} CCUT}//Personoop在Studentoopz中为匿名结构体字段,被称为提升字段//因此可以如下命名s3.name = "荷叶饭"s3.age = 16s3.school = "我不要上学"fmt.Println(s3) //{{荷叶饭,16} 我不要上学}
}// 1.定义父类
type Personoop struct {name stringage  int
}
// 2.定义子类//is-a的关系
type Studentoop struct {Personoop        //结构体嵌套模拟继承结构,提升字段,可以直接进行访问school    string //子类的新增属性
}

差不多就是这个意思,等下讲接口

方法(method)

方法的本质是一种函数,但是是定义了接受者的函数,这个接受者可以是很多种数据类型,还要结构体类型中的值或指针

所有给定统一类型的方法称为该类型的方法集。比如虾头太刀侠,可以登!龙!,还可以进行气刃大回旋,登龙和气刃大回旋就是虾头太刀侠的方法集

方法的名字可以重复,但是method区别调用者

语法:func(接受者)方法名(参数列表)(返回值列表){}

来写一个样例看看:

type Worker1 struct {name stringage  intsex  string
}//结构体定义部分
func (w Worker1) work() {fmt.Println(w.name, "在工作")
}//工作方法
func (p *Worker1) rest() {fmt.Println(p.name, "在休息")
}//休息方法func main(){w1 := Worker1{name: "张三", age: 18, sex: "男"}w1.work() //张三 在工作w2 := &Worker1{name: "李四", age: 18, sex: "女"}w2.rest() //李四 在休息}

方法可以重名,我们创建一个新的类和刚刚的类对比:

type Worker1 struct {name stringage  intsex  string
}
type Cat struct {name  stringcolor stringsex   string
}func (p *Worker1) printfInfo() {fmt.Println("name:", p.name, "age:", p.age, "sex", p.sex)
}
func (p *Cat) printfInfo() {fmt.Println("name:", p.name, "color:", p.color, "sex:", p.sex)
}func main(){w1 := Worker1{name: "张三", age: 18, sex: "男"}c1 := Cat{name: "艾露猫", color: "浅棕色", sex: "男"}c1.printfInfo() //name: 艾露猫 color: 浅棕色 sex: 男c1.name = "呆猫"c1.printfInfo()        //name: 呆猫 color: 浅棕色 sex: 男w1.printfInfo()        //name: 张三 age: 18 sex 男//方法可以重名,因为接受者不同}

新增方法和重写方法的区别:

func main(){//创建Personmethod类型p1 := Personmethod{"王二狗", 18}fmt.Println(p1) //{王二狗 18}p1.eat()        //父类的方法,吃盖浇面s1 := Studentmethod{Personmethod{"ruby", 18}, "XUPT"}fmt.Println(s1) //{{ruby 18} XUPT}s1.study()      //子类的新增方法,学生学习s1.eat()        //子类重写的方法,吃炸鸡}
// 继承中的方法
// 定义一个“父类”
type Personmethod struct {name stringage  int
}// 定义一个子类
type Studentmethod struct {Personmethodschool string
}// 定义一个父类方法
func (p Personmethod) eat() {fmt.Println("父类的方法,吃盖浇面")
}// 定义一个子类方法
func (p Studentmethod) study() {fmt.Println("子类的新增方法,学生学习")//和子类的类型一样,方法名不一样
}
func (p Studentmethod) eat() {fmt.Println("子类重写的方法,吃炸鸡")//重写是名字一样,类型不一样
}

接口(interface)

接口是对方法的抽象,例如:你会吃东西,说明你肯定是个生物,但是如果你又会吃东西,还会玩元神,那你就是个私宅;所以吃东西可以单独做一个接口,吃东西和玩元神也可以做另一个接口

这样叫通过方法来确定你的类型(鸭子类型)
go语言中,接口类型的实现关系,是非侵入式:只实现,不用在乎是谁实现的

java中要显示定义
eg:
class Mouse implements USB{}

package main
import ("fmt"
)
func main(){//1.创建mouse类型m1 := Mouse{"罗技小红"}fmt.Println(m1)//2.创建FlashDiskf1 := FlashDisk{"闪速64G"}fmt.Println(f1)testIterface(m1)//鼠标就会从testIterface中的USB中找到鼠标对应的start方法testIterface(f1)//同上}
func testIterface(usb USB) { //usb=m1 usb=f1usb.start()usb.end()
}//测试我们接口的函数type USB interface {start()end()
}//USB接口
func (m Mouse) start() {fmt.Println("Mouse.start")
}
func (m Mouse) end() {fmt.Println("Mouse.end")
}//对应的鼠标方法
func (f FlashDisk) start() {fmt.Println("FlashDisk.start")
}
func (f FlashDisk) end() {fmt.Println("FlashDisk.end")
}//对应的FlashDisk方法

也可以把main函数里面写成这样:

    var usb USBusb = m1usb.start()usb.end()usb = f1usb.start()usb.end()

可以更明显的看出接口对同类的不同对象方法的抽象

空接口

没有任何方法签名的接口叫空接口

写一个空接口:

package main
import ("fmt"
)
func main() {var a1 A = Dog{"黑犬"}var a2 A = People{"纸包鱼", 30}fmt.Println(a1, a2) //{黑犬} {纸包鱼 30}test1(a1)           //{黑犬}test1(a2)           //{纸包鱼 30}test2(a1)           //空接口 {黑犬}test2(a2)           //空接口 {纸包鱼 30}//空接口代表任意类型的使用slice1 := make([]interface{}, 0, 10)slice1 = append(slice1, a1, a2, 100, "abc") //[{黑犬} {纸包鱼 30} 100 abc]fmt.Println(slice1)
}func test1(a A) {fmt.Println(a)
}
func test2(a interface{}) {fmt.Println("空接口", a)
}// 空接口
type A interface {
}

空接口中不限制数据类型

接口嵌套,可以模拟oop的继承特性,也可以通过不同接口看是什么接口类型,可以把实现类型看成接口类型:

package main
import ("fmt"
)
func main() {var dog Dog = Dog{"青色"}dog.test11()dog.test22()dog.test33()fmt.Println("------分隔符------")var aa1 AA = dog //AA接口类型aa1.test11()fmt.Println("------分隔符------")var bb1 BB = dog //BB接口类型bb1.test22()fmt.Println("------分隔符------")var cc1 CC = dog //CC接口类型cc1.test11()cc1.test22()cc1.test33()
}
type AA interface {test11()
}
type BB interface {test22()
}
type CC interface {AABBtest33()
}func (d Dog) test11() {fmt.Println("test11...")
}
func (d Dog) test22() {fmt.Println("test22...")
} //如果test11和test22都能实现,则Dog同时是AA和BB的实现
func (d Dog) test33() {fmt.Println("test33...")
}

接口断言

我们可以通过接口来判断实现类型。那么如果是空接口呢?或者两个类都可以实现同一个接口下的方法呢?比如你会翻滚,烤肠机上的烤肠也会翻滚,那么如何区分你和烤肠呢?

package mainimport ("fmt""math"
)func main() {var t1 Triangle = Triangle{3, 4, 5}fmt.Println(t1.perimeter()) //12fmt.Println(t1.area())      //6var c1 Circle = Circle{5}fmt.Println(c1.perimeter()) //31.41592653589793fmt.Println(c1.area())      //78.53981633974483var s1 Shape                //Shape类型,但是没有确定为Triangle类型还是Circle类型s1 = t1                     //定义为Triangle类型fmt.Println(s1.perimeter())fmt.Println(s1.area())//fmt.Println(s1.a,s1.b,s1.c),打印不了,因为s1是Shape接口类型testShape(t1) //周长 12 面积 6testShape(c1) //周长 31.41592653589793 面积 78.53981633974483getType(t1)   //是三角形,三边为 3 4 5getType(c1)   //是圆形半径为 5getType(s1)   //是三角形,三边为 3 4 5var t2 *Triangle = &Triangle{3, 4, 5}getType(t2) //ins:*main.Triangle 0xc000058030//s:*main.Triangle 0xc0000260a0,地址不一样,值传递getType1(t2) //三角形结构体指针 3 4 5
}
func getType(s Shape) {//断言,判断接口对象是不是对应的实际类型//1.if分支if ins, ok := s.(Triangle); ok {fmt.Println("是三角形,三边为", ins.a, ins.b, ins.c)} else if ins, ok := s.(Circle); ok {fmt.Println("是圆形半径为", ins.radius)} else if ins, ok := s.(*Triangle); ok {fmt.Printf("ins:%T %p\n", ins, &ins)fmt.Printf("s:%T %p\n", s, &s)} else {fmt.Println("我也不知道")}
}
func getType1(s Shape) {//2.switch分支switch ins := s.(type) {case Triangle:fmt.Println("是三角形,三边为", ins.a, ins.b, ins.c)case Circle:fmt.Println("是圆形半径为", ins.radius)case *Triangle:fmt.Println("三角形结构体指针", ins.a, ins.b, ins.c)}
}
func testShape(s Shape) {fmt.Println("周长", s.perimeter(), "面积", s.area())
}// 1.定义一个接口
type Shape interface {perimeter() float64area() float64
}// 2.定义实现类
type Triangle struct {a, b, c float64
}func (t Triangle) perimeter() float64 {return t.a + t.b + t.c
}
func (t Triangle) area() float64 {p := t.perimeter() / 2s := math.Sqrt(p * (p - t.a) * (p - t.b) * (p - t.c))return s
}type Circle struct {radius float64
}func (c Circle) perimeter() float64 {return math.Pi * c.radius * 2
}
func (c Circle) area() float64 {return math.Pi * c.radius * c.radius
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

xhs 小红书 x-s web 分析

声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 有相关问题请第一时间头像私信联系我…

详解npm源及其使用方法

详解npm源及其使用方法 npm源是一个用于存储和提供npm包的服务器地址,npm在安装包时会通过这个源地址下载对应的依赖包。默认情况下,npm使用官方的npm源(https://registry.npmjs.org/),该源存储了海量的Node.js开源包…

QMT获取可转债行情数据方法介绍!支持QMT量化软件的券商平台?

获取可转债行情 为了获取转债的日线/1m/1d的k数据,以通过数据订阅形式获取最新行情subscribe_quote。如果您需要获取历史数据,可以使用download_history_data函数下载相关数据,然后使用get_market_data_ex函数提取所需的信息。这样&#xff…

两步搞定!手把手教你如何在VPS上自托管任何应用

你有没有遇到过这样的情况:看上去很酷的应用,想要自托管,结果在部署时却被各种配置、环境搭建搞得头疼不已?即使有些教程说得头头是道,操作起来依旧满头问号。你不是一个人!很多人都有这种困扰,包括我自己。不过,今天我想给你介绍一个神奇的工具——Sidekick。这个工具…

Mysql存储过程详细解读

目录 存储过程介绍 创建与调用 查看与删除 变量 系统变量 用户自定义变量 ​编辑局部变量 ​编辑​编辑IF判断 存储过程参数​编辑​编辑​编辑 CASE ​编辑 WHILE​编辑 ​编辑REPEAT​编辑​编辑 LOOP 游标 条件处理程序 存储函数 存储过程介绍 创建与调用 查…

【面试宝典】面试基础指导

目录 🍔 简历怎么写 🍔 ⾯试前针对项⽬撰写完成项⽬⽂档 🍔 ⾯试前 🍔 ⾯试中 4.1 投递简历当天没有收到⾯试邀约 4.2 讲解项⽬ 4.3 讲解知识 4.4 ⾯试中关于技术选型的演变 🍔 ⾯试后 🍔 小结 &…

【devops】rsync介绍和使用

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8…

--芯片测试--

目录 芯片逻辑是什么 芯片如何选型? 测试策略有什么 Alpha测试和Beta测试的区别? 主要区别 TOPS是什么 如何计算TOPS MAC单元是什么 频率的单位是什么 如何解决跨时钟域问题? 解释一下对异步电路的理解,以及如何实现同步…

Python酷库之旅-第三方库Pandas(123)

目录 一、用法精讲 546、pandas.DataFrame.ffill方法 546-1、语法 546-2、参数 546-3、功能 546-4、返回值 546-5、说明 546-6、用法 546-6-1、数据准备 546-6-2、代码示例 546-6-3、结果输出 547、pandas.DataFrame.fillna方法 547-1、语法 547-2、参数 547-3、…

828华为云征文 | 云服务器Flexus X实例:RAG 开源项目 FastGPT 部署,玩转大模型

目录 一、FastGPT 简介 二、FastGPT 部署 2.1 下载启动文件 2.2 开放端口权限 2.3 启动 FastGPT 三、FastGPT 运行 3.1 登录 FastGPT 3.2 知识库 3.3 应用 四、总结 本篇文章主要通过 Flexus云服务器X实例 部署 RAG 开源项目 FastGPT,通过 FastGPT 可以使…

Spring MVC 基础 : 文件、cookies的接收 ,REST响应

一、接受文件 在 Spring MVC 中,可以使用 RequestPart 注解来接收文件。这个注解常用于处理复杂的请求,如同时发送 JSON 数据和文件。RequestPart 非常适用于多部分请求(multipart requests),这在单个请求中同时发送文…

【深入理解SpringCloud微服务】了解微服务的熔断、限流、降级,手写实现一个微服务熔断限流器

【深入理解SpringCloud微服务】了解微服务的熔断、限流、降级,手写实现一个微服务熔断限流器 服务雪崩熔断、限流、降级熔断降级限流 手写实现一个微服务熔断限流器架构设计代码实现整体逻辑ProtectorAspect#aroundMethod(ProceedingJoinPoint)具体实现1、获取接口对…

【Linux 】开发利器:深度探索 Vim 编辑器的无限可能

🔥 个人主页:大耳朵土土垚 🔥 所属专栏:Linux系统编程 这里将会不定期更新有关Linux的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 文章目…

CANopen从站为什么总不上传PDO报文?

在CANopen网络中无法获取从站的TPDO数据?本文将为您解析可能的原因及解决方案。通过检查TPDO的通信参数和传输类型,确保主站与从站的数据同步,快速定位问题所在。 如果你的CANopen网络中已经确保接线和波特率都没有问题,但无论主站…

数学建模 第一讲 - 概论

一、什么是数学模型 一个栗子 例 1.1 一只装满水的圆柱型桶,底半径为 1米,高为 2米,底部有一直径为 0.1 米的洞。问桶流空要多少时间? 数学模型是对于一个特定的对象为了一个特定目标,根据事物的内在规律,作出一些必…

vs2022快捷键异常不起作用解决办法

安装了新版本的vs2022,安装成功后,发现快捷键发生异常,之前常用的快捷键要么发生改变,要么无法使用,比如原来注释代码的快捷键是ctrlec,最新安装版本变成了ctrlkc,以前编译代码的快捷键是F6或者…

搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(一)-概述

简介 此前的专栏介绍Onesearch1.0和2.0,详情参考4 参考资料,本文解释onesearch 3.0,从Elasticsearch6升级到Elasticsearch8代码实现 ,Elasticsearch8 废弃了high rest client,使用新的ElasticsearchClient,…

Java | Leetcode Java题解之第420题强密码检验器

题目&#xff1a; 题解&#xff1a; class Solution {public int strongPasswordChecker(String password) {int n password.length();int hasLower 0, hasUpper 0, hasDigit 0;for (int i 0; i < n; i) {char ch password.charAt(i);if (Character.isLowerCase(ch))…

BUUCTF-MISC-另外一个世界

下载题目文件解压获得一张jpg格式图片 按照经验&#xff0c;排查了文件中是否隐写了flag字段等&#xff0c;并未发现线索 但是把十六进制打开的文件翻到文章底部可以发现一段二进制数字 这段数字正好为56位&#xff0c;八位二进制可以转换成一位ASKII码&#xff0c;这里我怀疑他…

【devops】devops-ansible之介绍和基础使用

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…