go的结构体、方法、接口

news2024/11/16 1:28:08

结构体:

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

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

type Person struct {
	name string
	age  int
	sex  string
}

定义结构体法1:

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

定义结构体法2:

p2 := Person{}
	p2.age = 244
	p2.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.Person
	fmt.Printf("%T\n", p1)  //main.Person

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

定义结构体指针:

var pp1 *Person
	pp1 = &p1//p1是一个结构体,对p1取地址就是一个指针,所以可以画等号
	fmt.Println(pp1)
	fmt.Printf("%p,%T\n", pp1, pp1) //0xc0001040c0,*main.Person
	fmt.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 string
		age  int
	}{
		name: "无敌高考大王",
		age:  18,
	}
	fmt.Println(s2.name, s2.age)

好处:

简洁性

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

灵活性

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

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

type Worker struct {
	/*name string
	age  int*/
	string
	int //匿名字段
}

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

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

嵌套结构体:

结构体里套着结构体:

type Book struct {
	bookName string
	price    float64
}
type Studentbook struct {
	name string
	age  int
	book Book
}

定义法1:

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

​

定义法2:

	bb1 := Book{}
	bb1.bookName = "1984"
	bb1.price = 45.8
	ss1 := Studentbook{}
	ss1.name = "奥威尔"
	ss1.age = 24
	ss1.book = bb1
	fmt.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        //int
	var i2 = 100        //int
    var str1 mystr
	str1 = "嘻嘻"
//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和20
	type 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 main

import "fmt"

type BaseClass struct {
	PublicData  int //共有字段
	protectData int //protected,只能在包内私用,未导出的字段
}

// 模拟c++的继承,嵌套结构体
type DerivedClass struct {
	BaseClass
	derivedPrivate int
}

func (d *DerivedClass) AccessProtected() {
	d.protectData = 42 //访问我们未导出的protected字段
	fmt.Println("protectData==", d.protectData)
}
func main() {
	d := DerivedClass{}
	d.PublicData = 10
	fmt.Println("d.PublicData==", d.PublicData)
	d.AccessProtected()
	base := BaseClass{}
	base.protectData = 50 // 如果在c++里编译错误:无法访问,因为我们的protected是对于派生类可以被访问
	//但是在go里,我们不能把protected限定在类里,只能控制它在包内和包外是否可调用
	fmt.Println(base.protectData) //50
	fmt.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 main

import "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 Studentoop
	s3.Personoop.name = "老公"
	s3.Personoop.age = 18
	s3.school = "CCUT"
	fmt.Println(s3) //{{老公 18} CCUT}
	//Personoop在Studentoopz中为匿名结构体字段,被称为提升字段
	//因此可以如下命名
	s3.name = "荷叶饭"
	s3.age = 16
	s3.school = "我不要上学"
	fmt.Println(s3) //{{荷叶饭,16} 我不要上学}
}

// 1.定义父类
type Personoop struct {
	name string
	age  int
}
// 2.定义子类//is-a的关系
type Studentoop struct {
	Personoop        //结构体嵌套模拟继承结构,提升字段,可以直接进行访问
	school    string //子类的新增属性
}

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

方法(method)

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

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

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

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

来写一个样例看看:

type Worker1 struct {
	name string
	age  int
	sex  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 string
	age  int
	sex  string
}
type Cat struct {
	name  string
	color string
	sex   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 string
	age  int
}

// 定义一个子类
type Studentmethod struct {
	Personmethod
	school 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.创建FlashDisk
	f1 := FlashDisk{"闪速64G"}
	fmt.Println(f1)
    testIterface(m1)//鼠标就会从testIterface中的USB中找到鼠标对应的start方法
	testIterface(f1)//同上

}
func testIterface(usb USB) { //usb=m1 usb=f1
	usb.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 USB
	usb = m1
	usb.start()
	usb.end()
	usb = f1
	usb.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 {
	AA
	BB
	test33()
}

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 main

import (
	"fmt"
	"math"
)

func main() {
	var t1 Triangle = Triangle{3, 4, 5}
	fmt.Println(t1.perimeter()) //12
	fmt.Println(t1.area())      //6
	var c1 Circle = Circle{5}
	fmt.Println(c1.perimeter()) //31.41592653589793
	fmt.Println(c1.area())      //78.53981633974483
	var 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 面积 6
	testShape(c1) //周长 31.41592653589793 面积 78.53981633974483
	getType(t1)   //是三角形,三边为 3 4 5
	getType(c1)   //是圆形半径为 5
	getType(s1)   //是三角形,三边为 3 4 5
	var 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() float64
	area() 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() / 2
	s := 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.coloradmin.cn/o/2157690.html

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

相关文章

老程序员的数字游戏开发笔记(三) —— Godot出你的第一个2D游戏(一篇文章完整演绎Godot制作2D游戏的全部细节)

忽略代码,忽略素材,忽略逻辑! 游戏的精髓是人性与思想,我一篇一篇地制作,不想动手的小伙伴看一看就可以,感受一下也不错,我们是有目的性的,这一切都是为今后的AI融合打基础&#xf…

详解CORDIC算法以及Verilog实现并且调用Xilinx CORDIC IP核进行验证

系列文章目录 文章目录 系列文章目录一、什么是CORDIC算法?二、CORDIC算法原理推导三、CORDIC模式3.1 旋转模式3.2 向量模式 四、Verilog实现CORDIC4.1 判断象限4.2 定义角度表4.3 迭代公式 五、仿真验证5.1 matlab打印各角度的正余弦值5.2 Verilog仿真结果观察 六、…

大模型学习方向不知道的,看完这篇学习思路好清晰!!

入门大模型并没有想象中复杂,尤其对于普通程序员,建议采用从外到内的学习路径。下面我们通过几个步骤来探索如何系统学习大模型: 1️⃣初步理解应用场景与人才需求 大模型的核心应用涵盖了智能体(AI Agent)、微调&…

NodeFormer:一种用于节点分类的可扩展图结构学习 Transformer

人工智能咨询培训老师叶梓 转载标明出处 现有的神经网络(GNNs)在处理大规模图数据时面临着一些挑战,如过度平滑、异质性、长距离依赖处理、边缘不完整性等问题,尤其是当输入图完全缺失时。为了解决这些问题,上海交通大…

RK3588NPU驱动版本升级至0.9.6教程

RK3588NPU驱动版本升级至0.9.6教程 1、下载RK3588NPU驱动2、修改NPU驱动源码2.0 修改MONITOR_TPYE_DEV写错问题2.1 解决缺少函数rockchip_uninit_opp_table问题2.2 解决缺少函数vm_flags_set、vm_flag_clear的问题2.3 内核编译成功2.4 重新构建系统 3、注意事项4、其他问题处理…

故障诊断 | 基于双路神经网络的滚动轴承故障诊断

故障诊断 | 基于双路神经网络的滚动轴承故障诊断 目录 故障诊断 | 基于双路神经网络的滚动轴承故障诊断效果一览基本介绍程序设计参考资料效果一览 基本介绍 基于双路神经网络的滚动轴承故障诊断 融合了原始振动信号 和 二维信号时频图像的多输入(多通道)故障诊断方法 单路和双…

【原创】java+springboot+mysql党员教育网系统设计与实现

个人主页:程序猿小小杨 个人简介:从事开发多年,Java、Php、Python、前端开发均有涉猎 博客内容:Java项目实战、项目演示、技术分享 文末有作者名片,希望和大家一起共同进步,你只管努力,剩下的交…

【Linux】常用指令【更详细,带实操】

Linux全套讲解系列,参考视频-B站韩顺平,本文的讲解更为详细 目录 一、文件目录指令 1、cd【change directory】指令 ​ 2、mkdir【make dir..】指令​ 3、cp【copy】指令 ​ 4、rm【remove】指令 5、mv【move】指令 6、cat指令和more指令 7、less和…

【爬虫工具】小红书评论高级采集软件

用python开发的爬虫采集工具【爬小红书搜索评论软件】,支持根据关键词采集评论。 思路:笔记关键词->笔记链接->评论 软件界面: 完整文章、详细了解: https://mp.weixin.qq.com/s/C_TuChFwh8Vw76hTGX679Q 好用的软件一起分…

去除字符串或字符串数组中字符串左侧的空格或指定字符numpy.char.lstrip()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 去除字符串或字符串数组中 字符串左侧的空格或指定字符 numpy.char.lstrip() [太阳]选择题 请问关于以下代码表述错误的选项是? import numpy as np print("【执行】np.cha…

2024/9/22

系列文章目录 文章目录 系列文章目录前言一、两条腿走路二、编程语言能力提升1.廖雪峰的python课2.Leetcode(数据结构题) 三、机器学习能力提升1.统计学习方法 李航2.kaggle竞赛 四、神经网络能力提升1.神经网络与深度学习 邱锡鹏2.一套自己的万金油模板…

寄存器与内存

第三课:寄存器与内存、中央处理器(CPU)、指令和程序及高级 CPU 设计-CSDN博客 锁存器 引入 ABO0(开始状态)001(将A置1)110(将A置0)11 无论怎么做,都没法从1变…

Windows PowerShell相关笔记

之前我写的一篇,把我的PS(power shell)该了配置文件 pyqt5vscode 配置坑笔记_vscode使用pyqt command failed-CSDN博客 文件里写的自动加载conda #region conda initialize # !! Contents within this block are managed by conda init !!…

[Python]一、Python基础编程(2)

F:\BaiduNetdiskDownload\2023人工智能开发学习路线图\1、人工智能开发入门\1、零基础Python编程 1. 文件操作 把⼀些内容 ( 数据 )存储存放起来,可以让程序下⼀次执⾏的时候直接使⽤,⽽不必重新制作⼀份,省时省⼒ 。 1.1 文件的基本操作 1. 打开文件 2. 读写操作 3. 关闭…

基于YOLOv5s的瓶装酒瑕疵检测(附数据集与操作步骤)

本文主要内容:详细介绍了瓶装酒瑕疵检测的整个过程,从创建数据集到训练模型再到预测结果全部可视化操作与分析。 文末有数据集获取方式,请先看检测效果 现状 在酒类生产领域,品质极为重要。瓶装酒的外观瑕疵,不仅影响消费者的购…

基于Ambari搭建hadoop生态圈+Centos7安装教程V2.0优化版(本篇博客写的较为详细,可能比较多,请耐心看)

当我们学习搭建hadoop的时候,未免也会遇见很多繁琐的事情,比如很多错误,需要解决。在以后公司,也不可能让你一个一个搭建hadoop,成千上万的电脑,你再一个个搭建,一个个报错,而且每台…

飞书获取用户及部门信息

1、进入企业后台管理,创建一个企业自建应用 ,获取App ID,App Secret 2、 对应用设置api权限及数据权限 3、Java客户端获取用户,部门信息 有两种方式可以获取:1、api 2、sdk的方式 我这里采用sdk的方式,…

如何给文件夹里面的文件批量添加前缀和编号(利用C#写的小工具)

运行结果 将上面的文件编号效果 下载过后启动这个程序即可(这个程序灵感来源是上次给美术资源分类和编号的时候给我干吐了,所以写了这个工具) 体验链接:laozhupeiqia/批处理 --- laozhupeiqia/批处理 (github.com) 如果对你有帮助…

【C++】面向对象编程的三大特性:深入解析继承机制

C语法相关知识点可以通过点击以下链接进行学习一起加油!命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与QueuePriori…

近几年来说最有效率的编程语言和市场最认可的编程语言分别是什么?

在过去的几年中,编程语言的效率和市场认可度在不断演变。不同的语言适用于不同的领域和场景,因而编程语言的“效率”和“市场认可”需要根据具体应用来分析。本文将从两个角度入手,分别探讨近几年中被认为最有效率和最受市场认可的编程语言。…