【TypeScript】TS入门到实战(详解:高级类型)

news2025/1/10 19:10:14

目录

第三章、TypeScript的数据类型

3.1 TypeScript的高级类型

3.1.1 class

3.1.1.1 熟悉class类

3.1.1.2 class类继承的两种方式

3.1.1.3 class类的5种修饰符

3.1.2 类型兼容

3.1.3 交叉类型

3.1.4 泛型

3.1.4.1 创建泛型函数

3.1.4.2 泛型函数的调用

3.1.4.3 泛型约束

3.1.4.4 泛型接口

3.1.4.5 泛型类

3.1.4.6 泛型工具类型

3.1.5 索引签名类型

3.1.6  映射类型


第三章、TypeScript的数据类型

3.1 TypeScript的高级类型

3.1.1 class

3.1.1.1 熟悉class类
  • 引言
class Person {}
const p = new Person()

当创建一个Person类时,添加了实例对象p,由类型推论可以知道它的类型是Person;说明TS 中的 class,不仅提供了 class 的语法功能,也作为一种类型存在。接下来跟着小编一起理解class吧。

  • 初始化属性
class Person {
    age: number // 适用没有默认值
    name = 'VE' // 适用于有默认值
}
  1. 声明成员 age,类型为 number(没有初始值)。
  2. 声明成员 name,并设置初始值,此时,可省略类型注解(TS 类型推论 为 string 类型)。
  3. 当没有默认赋值时,需要自定义属性的类型,否则会默认为any类型赋值后,属性的类型会与赋值的类型一致,赋值的类型ts会类型推论
  4. 看下图的几种情况:

 

  • 构造函数
class Person {
    age: number
    name: string

    constructor (name: string, age: number){ // 初始化实例对象使用的,写了contructor函数后初始化实例对象时也需要传参从而初始化实例中的属性
        this.age = age
        this.name = name
    }
}
const p = new Person('10', 10)
  1. 只有初始化(比如,age: number)后,才可以通过 this.age 来访问实例成员。
  2. 需要为构造函数指定类型注解,否则会被隐式推断为 any;构造函数不需要返回值类型。
  3. constructor构造函数是初始化实例对象使用的,写了contructor函数后初始化实例对象时也需要通过传参从而初始化实例中的属性参数顺序跟constructor一致

 

  • 实例方法
class Point {
    x: number
    y: number

    scale (n: number): void{
        this.x *= n
        this.y *= n
    }
}
  1. 方法初始化,它的的类型注解(参数和返回值)与函数用法相同

3.1.1.2 class类继承的两种方式

类继承的两种方式:1、extends(继承父类) 2、implements(实现接口)
注意:JS 中只有 extends,而 implements 是 TS 提供的。

  • extends(继承父类)
class Animal { // 这是父类Animal 
    distance: string = '10' // 父类中的属性
    move () { // 父类中的方法
        console.log('move along')
    }
}

class Dog extends Animal { // 子类 Dog 继承父类 Anima
    bark () { // 子类自身的方法
        console.log('汪汪汪~')
    }
}

const dog = new Dog() // dog是Dog的实例对象,

// 从而dog同时具有了父类 Animal 和 子类 Dog 的所有属性和方法
dog.move()
dog.bark()
dog.distance = '20'
console.log('距离', dog.distance)

  1. 通过 extends 关键字实现继承。
  2. 子类 Dog 继承父类 Animal,则 Dog 的实例对象 dog 就同时具有了父类 Animal 和 子类 Dog 的所有属性和方法。
  • implements(实现接口): 这是ts新增的,顾名思义就是对一个接口的实现

interface Singable { // 这是添加的一个接口,定义了Singable有哪些属性和方法的类型
    name: string 
    sing: () => void
    toSing(): void
}

class Person implements Singable { // Person类是对Singable接口的实现
    name = 'VE'
    sing = () => { // 函数方面是箭头函数还是普通函数需要我们自己规范
        console.log('你是我的小啊小苹果')
    }
    toSing(): void {
        console.log('去ktv唱歌')
    }
}

const p = new Person() // p是Person的一个实例对象

// 从而拥有了Singable 接口 指定的所有方法和属性
console.log(p.name)
p.sing()
p.toSing()

  1. 通过 implements 关键字让 class 实现接口。
  2. Person 类实现接口 Singable 意味着,Person 类中必须提供 Singable 接口中指定的所有方法和属性。
3.1.1.3 class类的5种修饰符

可见性修饰符包括:1、public(公有的) 2、protected(受保护的) 3、private(私有的)4、readonly(只读修饰符)5、static(静态的)

  • public(公有的)

class Animal {
    public move () { // 在父类的方法中添加pubilc(默认,可省略)
        console.log('move along')
    }
}
class Dog extends Animal { // 子类
    bark () {
        console.log('汪汪汪~')
    }
}

class Cat extends Animal { // 子类
    bark () {
        console.log('喵~喵~喵~')
    }
}

const dog = new Dog() // 由于父类设置的为pubilc修饰符,所有其子类实例可以调用父类的方法

dog.move()
dog.bark()

const cat = new Cat() // 由于父类设置的为pubilc修饰符,所有其子类实例可以调用父类的方法

cat.move()
cat.bark()

  1. 在类属性或方法前面添加 public 关键字,来修饰该属性或方法是共有的
  2.  因为 public 是默认可见性,所以,可以直接省略
  • protected(受保护的)

class Animal {
    protected move () { // 将方法添加protected关键字设置成受保护的,
        console.log('move along')
    }
    toMove () {
        this.move() // 在父类本身中只能通过this访问受保护的属性/方法
    }
}
class Dog extends Animal {
    bark () {
        console.log('汪汪汪~')
        this.move() // 在子类中也只能通过this访问受保护的属性/方法
    }
}
// const animal = new Animal() // 但是他们的实例不能访问到受保护的属性和方法
// animal.move() // 本身实例调用会报错属性move受保护,只能在类“Animal”及其子类中访问

const dog = new Dog()

// dog.move() // 子类调用会报错属性move受保护,只能在类“Animal”及其子类中访问
dog.bark() // 可以通过提供方法添加新的方法从而间接访问
console.log('=====')
dog.toMove()

  1. 在类属性或方法前面添加 protected 关键字,来修饰该属性或方法是受保护的
  2. 在子类的方法内部可以通过 this 来访问父类中受保护的成员,但是,对其声明所在类和子类不可见!
  • private(私有的)

class Animal {
    private move () {
        console.log('move along') // 将方法添加private 关键字设置成私有的,
    }
    toMove () {
        this.move() // 只能在当前类中访问
    }
}
class Dog extends Animal {
    bark () {
        console.log('汪汪汪~')
        // this.move() // 在子类的方法中也不能访问
    }
}
// const animal = new Animal()
// animal.move() // 本身实例调用会报错属性move斯私有属性,只能在类“Animal”中访问

const dog = new Dog()

// dog.move() // 子类调用会报错属性move为私用属性,只能在类“Animal”中访问
dog.bark()
console.log('=====')
dog.toMove()  // 但是子类可以通过调用父类提供的方法从而间接的访问父类的私有属性

 

  1. 在类属性或方法前面添加 private 关键字,来修饰该属性或方法是私有的
  2.  私有的属性或方法只在当前类中可见,对子类和实例对象也都是不可见的!
  • readonly(只读修饰符)

class Animal {
    readonly species: string = '爬行动物' // 修饰属性为只读是, 仅可在构造函数中修改
    move () {
        // this.species = '飞行动物' // 报错无法赋值,species为只读属性
        console.log('move along')
    }
    constructor(species: string){
        this.species = species
    }
}
class Dog extends Animal {
    bark () {
        console.log('汪汪汪~')
    }
}

const dog = new Dog('爬行')

dog.bark()
console.log('dog', dog.species)

 

  1. 使用 readonly 关键字修饰该属性是只读的,注意只能修饰属性不能修饰方法。
  2. 注意:只要是readonly来修是属性,必须手动提供明确的类型,属性 species 后面的类型注解(比如,此处的 string)如果不加,则 species 的类型为 爬行动物 (字面量类型)。
  3. 仅可在构造函数中修改(也就是初始化时)
  4. 接口或者 {} 表示的对象类型,也可以使用 readonly
// 接口或者 {} 表示的对象类型,也可以使用 readonly
interface IPerson {
    readonly name: string
}

let p: IPerson = {
    name: 'VE'
}

let per: { readonly name: string, age: number } = {
    name: 'VE',
    age: 18
}

// p.name = 'LO' // 如果没加readonly是可以修改的,但是加了之后会报错为只读属性,无法赋值
// per.name = 'LO'
per.age = 20
  • static(静态的)
class Animal {
    // 普通属性
    name: string
    // 静态属性
    static gander: string = '女'
  
    // 构造函数前不能添加 static
    constructor (name: string) {
        this.name = name
  
        // 访问静态属性,需要通过 【类名.属性】访问
        console.log(this.name, Animal.gander)
    }
  
    // 普通方法
    sayHi () {
        console.log('hello你们好')
    }
  
    // 静态方法
    static sayStatic () {
        console.log(Animal.gander)
    }
}
// 实例化对象
const per = new Animal('花花')
// 访问普通方法,通过实例
per.sayHi()
// 访问静态方法,要通过 【类名.方法】访问
Animal.sayStatic()

  1. 使用 static 关键字修饰该属性/方法是静态的
  2. 静态成员 在使用时通过 类名.静态成员 这种语法来调用的,而不是通过 this实例

3.1.2 类型兼容

  • 目前有两种类型系统:1 Structural Type System(结构化类型系统) 2 Nominal Type System(标明类型系统)
  • TS 采用的是结构化类型系统,也叫做 duck typing(鸭子类型),类型检查关注的是值所具有的形状。也就是说,在结构类型系统中,如果两个对象具有相同的形状,则认为它们属于同一类型。(可以这么理解但是,该说法并不准确)。用于确定一个类型是否能赋值给其他类型
  • 对于对象类型来说,y 的成员至少与 x 相同,则 x 兼容 y(成员多的可以赋值给少的)
  • 例子1:
class Point {number1 = 10; number2 = 9}
class Point2D {number1 = 16; number2 = 12}

const p: Point = new Point2D()
console.log('p', p.number1, p.number2)

  1. Point 和 Point2D 是两个名称不同的类。
  2. 变量 p 的类型被显示标注为 Point 类型,但是,它的值却是 Point2D 的实例,并且没有类型错误。
  3. 因为 TS 是结构化类型系统,只检查 Point 和 Point2D 的结构是否相同(结果是相同,都具有 x 和 y 两个属性,属性类型也相同)。
  4. 但是,如果在 Nominal Type System(标明类型系统) 中(比如,C#、Java 等),它们是不同的类,类型无法兼容。
  5. 这里我们可以理解p被类型标注了Point的number1与number2,分别都是number类型,最后被赋值了Point2D
  • 例子2:兼容可以立即成向下兼容,在class中定义:成员多的可以赋值给成员少的(理解,左边的参数必须都有,而右边赋值的则是至少需要包含左边参数)
class Point {number1 = 10; number2 = 9}
class Point2D {number1 = 16; number2 = 12}
class Point3D {number1 = 17; number2= 1; numbe3 = 20 }
const p: Point = new Point2D()
const p1: Point2D = new Point3D() // 成员多的 Point3D 可以赋值给成员少的Point2D / Point
console.log('p', p.number1, p.number2)

…… 

3.1.3 交叉类型

  • 交叉类型(&):功能类似于接口继承(extends),用于组合多个类型为一个类型(常用于对象类型

interface Person { // 第一个接口定义了一部分类型
    name: string
}
interface Contact { // 第二个接口定义了不部分类型
    phone: string
}

type PersonDetail = Person & Contact // 定义新的类型利用&交叉类型合并, 注hengsm意新的类型用tpye类型别名声明的

let person: PersonDetail = { // 新的类型同时拥有上面的两种声明类型
    name: 'zs',
    phone: '177 5490 0987'
}
  1. 使用交叉类型后,新的类型 PersonDetail 就同时具备了 Person 和 Contact 的所有属性类型。
  2.     相当于type PersonDetail = { name: string, phone: string }
  • 交叉类型(&)和接口继承(extends)的对比

-- 使用extends

interface A {
    name: string
    fn: (number: number) => void
}
interface B extends A {
    gander: string
    //  fn: (number: string) => void
}
const obj: B = {
    name: 'VE',
    fn: (number: number) => {},
    gander: '女'
}

-- 使用交叉类型

interface A {
    name: string
    fn: (number: number) => number
}
interface B {
    // name: number
    fn: (number: string) => string
}
type C = B & A
const obj: C = {
    // name,
    name: '',
    fn: (number) => {
        return number
    }
}

-- 相同点:都可以实现对象类型的组合。
-- 不同点:两种方式实现类型组合时,对于同名属性之间,处理类型冲突的方式不同
       extends 不支持相同属性/方法的继承,会报错类型不兼容
       & 支持相同属性/方法的继承可以理解成利用联合类型 & 连接,两种类型同时具备才可,否则会报错,不可分配

3.1.4 泛型

  • 泛型是可以在保证类型安全前提下,让函数等与多种类型一起工作,从而实现复用,常用于:函数、接口、class 中。

3.1.4.1 创建泛型函数
  • 引入思考:目前有一个需求,创建一个 id 函数,传入什么数据就返回该数据本身(也就是说,参数和返回值类型相同)

// 实现方法一:手动限制一个类型,缺点也很明显,我们只能传number数据类型,传其他数据类型时会报错
function id_first(value: number) {
    return value
}
// 实现方法二:不限制数据类型,那么ts本身类型推断,则会将传参推断为any,失去了ts的意义
function id_second(value) {
    return value
}
  •  实现方法:创建泛型函数,泛型在保证类型安全(不丢失类型信息)的同时,可以让函数等与多种不同的类型一起工作,灵活可复用。
// 实现方法:创建泛型函数,泛型在保证类型安全(不丢失类型信息)的同时,可以让函数等与多种不同的类型一起工作,灵活可复用。
function id<Type>(value: Type): Type {
    return value
}

  1.  语法:在函数名称的后面添加 <>(尖括号)尖括号中添加类型变量(可自定义语义化名称),比如此处的 Type。
  2. 该函数中类型变量 Type,是一种特殊类型的变量,它处理类型而不是值。
  3.  该类型变量相当于一个类型容器,能够捕获用户提供的类型(具体是什么类型由用户调用该函数时指定)。
  4.  因为 Type 是类型,因此可以将其作为函数参数和返回值的类型,表示参数和返回值具有相同的类型。
  5. 类型变量 Type,可以是任意合法的变量名称
3.1.4.2 泛型函数的调用
  • 正常调用 
function id<Type>(value: Type): Type {
    return value
}

// 调用泛型函数:既要传类型,也要传参数
const num = id<number>(1)
const str = id<string>('10')
const arr = id<(number | string)[]>(['10', '1', 10])

  1. 语法:在函数名称的后面添加 <>(尖括号),尖括号中指定传参的具体的类型,比如,此处的 number。
  2. 当传入类型 number 后,这个类型就会被函数声明时指定的类型变量 Type 捕获到。
  3.  此时,Type 的类型就是 number,所以,函数 id 参数和返回值的类型也都是 number
  • 简化调用
function id<Type>(value: Type): Type {
    return value
}

// <类型> 可以不写
let sp_num = id(10)
let sp_str = id('10')
let sp_arr = id(['10', '1', 10])

主要注意:这种方法是利用类型推断实现的,直接传参要与前面带类型的要区分 

  1. 例如sp_num、sp_str变量,我们能发现函数被推断成id<10>(value: 10): 10 字面量类型,最终返回数字10才使得sp_num推断成number类型
  2. 例如sp_arr变量,函数被推断<(string | number)[]>(value: (string | number)[]): (string | number)[],最终返回结果['10', '1', 10]使得sp_arr推断成(string | number)[]类型
  3.  如果我们期望第1点最终是number类型而不是字面量类型,但是类型推断又是给我们推断成字面量类型,我们还是需要传类型的:id<number>(10)
3.1.4.3 泛型约束
  • 默认情况下泛型函数的类型变量 Type 可以代表多个类型,这导致无法访问任何属性,如下:

function id_view<Type>(value: Type): Type {
    console.log('长度', value.length) // 报错原因:Type 可以代表任意类型,无法保证一定存在 length 属性,比如 number 类型没有 length。
    return value
}

  • 于是,就需要为泛型添加约束来收缩类型(缩窄类型取值范围),添加泛型约束收缩类型,主要有以下两种方式:1、指定更加具体的类型 2、添加约束

  • 1、指定更加具体的类型

例如:将类型修改为 Type[](Type 类型的数组),因为只要是数组就一定存在 length 属性,因此就可以访问了

function id_view<Type>(value: Type[]): Type[] { // 将类型修改为 Type[](Type 类型的数组),因为只要是数组就一定存在 length 属性,因此就可以访问了
    console.log('长度', value.length)
    return value
}

id_view([1, 2])
id_view<number | string>([1, '2'])
id_view<number[]>([1, 2]) // 注意添加<类型>是的写法,由于我们已经在类型中写了Type[],所以使用时不需要再加[]

注意书写:(类型可不传,ts会通过类型断言得到)

 报错:

  • 2、添加约束 
interface ILength { length: number } // 创建描述约束的接口 ILength,提供length属性


function id_view<Type extends ILength>(value: Type): Type { // 对Type添加约束,通过 extends 关键字使用ILength接口
    console.log('长度', value.length)
    return value
}

// 使用类型约束之后我们在调用时就必须需要传具有 length 属性的类型(string/array…),否则调用会报错
// id_view<number>(10) // 会报错number类型不满足约束的ILength
id_view('10')
id_view<string>('10')
// id_view<{name: string, age: number}>({name: 'VE', age: 23}) // 会报错

  1. 创建描述约束的接口 ILength,该接口要求提供 length 属性
  2. 通过 extends 关键字使用该接口,为泛型(类型变量)添加约束。
  3. 该约束表示:传入的类型必须具有 length 属性
  • 泛型的类型变量可以有多个,并且类型变量之间还可以约束

function getProp<Type, Key extends keyof Type>(obj: Type, key: Key) { // keyof 关键字接收一个对象类型,生成其键名称(可能是字符串或数字)的联合类型
    return obj[key]
}
let person = {name: 'VE', age: 23}
const personName = getProp(person , 'name')
console.log('personName', personName)

  1. 添加了第二个类型变量 Key,两个类型变量之间使用(,)逗号分隔。
  2.  keyof 关键字接收一个对象类型,生成其键名称(可能是字符串或数字)的联合类型
  3. 本示例中 keyof Type 实际上获取的是 person 对象所有键的联合类型,也就是:'name' | 'age'。
  4. 类型变量 Key 受 Type 约束,可以理解为:Key 只能是 Type 所有键中的任意一个,或者说只能访问对象中存在的属性

3.1.4.4 泛型接口
  • 接口配合泛型使用,以增加其灵活性,复用性

interface idFunc<Type> {
    id: (vlue: Type) => Type
    ids: () => Type[]
}
const obj: idFunc<number> = { // 使用泛型接口时,必须需要显式指定具体的类型
    id(num) {
        return num
    },
    ids() {
        return [1, 2]
    }
}

  1. 语法:在接口名称的后面添加 <类型变量>,那么,这个接口就变成了泛型接口。
  2. 接口的类型变量,对接口中所有其他成员可见,也就是接口中所有成员都可以使用类型变量
  3. 使用泛型接口时,需要显式指定具体的类型(比如,此处的 IdFunc<number>)。
  4. 此时,id 方法的参数和返回值类型都是 number;ids 方法的返回值类型是 number[]。
  • JS 中的数组在 TS 中就是一个泛型接口:当我们在使用数组的方法时,TS 会根据数组的不同类型,来自动将类型变量设置为相应的类型,如下:

const strsArr = ['a', 'b', 'c']
const arr1 = [1, 2, 'a']
strsArr.sort()
arr1.sort()
arr1.forEach(()=>{})

 

3.1.4.5 泛型类
  • 使用class类 配合泛型来使用

  • 创建泛型类并使用

关于创造泛型类涉及到的报错:

【TypeScript 类报错】Property ‘name‘ has no initializer and is not definitely assigned in the constructor-CSDN博客

class GenericNumber<NumType> { // 创建泛型类
    defaultValue: NumType
    add?: ( x: NumType, y: NumType ) => NumType
    
    constructor(defaultValue: NumType) { // 创建构造函数
        this.defaultValue = defaultValue
    }
}
const myNum = new GenericNumber<number>(10) // 类似于泛型接口,在创建 class 实例时,在类名后面通过 <类型> 来指定明确的类型。
myNum.defaultValue = 10
// 初始化方法
myNum.add = function(a, b) {
    return a + b
}
// 之后调用方法
const value = myNum.add(1, 2)
console.log(myNum.defaultValue, value)

(针对于泛型类里的方法创造了实例之后一定要先初始化再调用)

3.1.4.6 泛型工具类型
  • TS 内置了一些常用的工具类型,来简化 TS 中的一些常见操作,它们都是基于泛型实现的(泛型适用于多种类型,更加通用),并且是内置的,可以直接在代码中使用。

  • 常用的:1、Partial<Type>  2、 Readonly<Type> 3、 Pick<Type, Keys> 4 、Record<Keys, Type>

  • 1、Partial<Type>:用来构造(创建)一个类型,将 Type 的所有属性设置为可选
interface Props {
    id: string
    children: number[]
}

// 构造出来的新类型 PartialProps 结构和 Props 相同,但所有属性都变为可选的。鼠标悬浮在PartialProps上可以发现PartialProps的属性都添加了?:表示可有可无
type PartialProps = Partial<Props> 
let partialVal: PartialProps = {} // 添加Partial后,参数可写可不写
let noPartialVal: Props = { // 未添加Partial,使用该类型字段必须都传
    id: '1',
    children: [1, 2]
}

  • 2、Readonly<Type> 用来构造一个类型,将 Type 的所有属性都设置为 readonly(只读)
interface Props {
    id: string
    children: number[]
}

type readonlyProps = Readonly<Props> // 会给每一个类型前面添加一个 readonly 修饰
let readonVal: readonlyProps = { // 一旦定义里面的属性就无法修改
    id: '001',
    children: [1, 2, 3]
}
// readonVal.id = '002' // 无法修改,报错无法赋值,为只读属性

  • 3、Pick<Type, Keys> 从 Type 中选择一组已有的属性来构造新类型
interface Props {
    id: string
    children: number[]
}

type PickProps = Pick<Props, 'id'>
let PickVal: PickProps = {
    id: '',
}
// 如果传多个使用 | 连接,选择的不能是类型中没有的属性
type PickProps = Pick<Props, 'id' | 'children'> 
let PickVal: PickProps = {
    id: '',
    children: [1, 2, 3]
}
  • 4、Record<Keys,Type> 构造一个对象类型,属性键为 Keys ,使用 | 连接多个属性,属性类型为 Type。
interface Props {
    id: string
    children: number[]
}

type RecordProps = Record<'id', Props>
let RecordVal: RecordProps = {
    id: {
        id: '',
        children: [1, 2]
    }
}
type RecordProps2 = Record<'id' | 'title', string>
let RecordVal2: RecordProps2 = {
    id: '',
    title: ''
}

3.1.5 索引签名类型

  • 绝大多数情况下,我们都可以在使用对象前就确定对象的结构,并为对象添加准确的类型。
  • 使用场景:当无法确定对象中有哪些属性(或者说对象中可以出现任意多个属性),此时,就用到索引签名类型了
interface AnyObject {
    [key: string]: number
}
let obj: AnyObject = {
    a: 1,
    b: 22,
    1: 2
}

  1. 使用 [key: string] 来约束该接口中允许出现的属性名称。表示只要是 string 类型的属性名称,都可以出现在对象中
  2.  这样,对象 obj 中就可以出现任意多个属性(比如,a、b 等)。
  3. key 只是一个占位符,可以换成任意合法的变量名称。
  4. 隐藏的前置知识:JS 中对象({})的键是 string 类型的。
interface MyArray<T> {
    [key: number]: T // 索引都是数字,数组符合要求,T规定类型
}
let arr: MyArray<number> = [1, 2, 3]
  1. 在 JS 中数组是一类特殊的对象,特殊在数组的键(索引)是数值类型。
  2. 并且,数组也可以出现任意多个元素。所以,在数组对应的泛型接口中,也用到了索引签名类型

3.1.6  映射类型

小编重开一篇文章单独讲。

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

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

相关文章

【操作与配置】Linux的CPU深度学习环境

Conda安装 可浏览官网&#xff1a;Miniconda — Anaconda 文档 这四条命令会快速而且悄悄地安装最新的64位安装程序&#xff0c;然后清理安装过程中产生的文件。如果需要安装 Linux 版本的其他版本或架构的 Miniconda&#xff0c;只需要在命令中更改安装程序的名称。 mkdir …

【C++】const详解

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文作为 JohnKi &#xff0c;引用了部分大佬的案例 &#x1f4e2;未来很长&#xff0c;…

【Kali-linux for WSL】图形化界面安装

文章目录 前言图形化界面安装 前言 之前在WSL中安装了Kali 启动之后发现什么都没有&#xff01;&#xff01;&#xff01; 那我还怎么学习渗透技术&#xff1f;&#xff1f;&#xff1f; 看来&#xff0c;得改进下我的kali-linux for wsl&#xff0c;安装个图形化界面 图形化…

JCR一区级 | Matlab实现BO-Transformer-LSTM多变量回归预测

JCR一区级 | Matlab实现BO-Transformer-LSTM多变量回归预测 目录 JCR一区级 | Matlab实现BO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现BO-Transformer-LSTM多变量回归预测&#xff0c;贝叶斯优化Transformer结合LSTM长…

【Python】Python中的常量与变量

常量与变量 导读一、新建项目二、常量2.1 字面常量2.2 特殊常量 三、变量3.1 变量的定义3.2 变量的命名3.2.1 关键字 结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我们详细介绍了Python环境的搭建过程&#xff0c;…

一键转换,高效管理:引领文件批量改后缀名与TXT转DOCX格式新潮流

在这个数字化时代&#xff0c;文件管理和格式转换成为了我们日常工作中不可或缺的一部分。然而&#xff0c;手动更改文件后缀名以及将TXT文件转换为DOCX格式&#xff0c;不仅耗时耗力&#xff0c;还容易出错。幸运的是&#xff0c;我们有了文件批量改名高手这款强大的工具&…

【JAVA多线程】JDK中的各种锁,看这一篇就够了

目录 1.概论 1.1.实现锁的要素 1.2.阻塞队列 1.3.Lock接口和Sync类 2.各种锁 2.1.互斥锁 2.1.1.概论 2.1.2.源码 1.lock() 2.unlock() 2.2.读写锁 2.3.Condition 2.3.1.概论 2.3.2.底层实现 1.概论 1.1.实现锁的要素 JAVA中的锁都是可重入的锁&#xff0c;因为…

固定网国内数据传送业务经营许可证

一、国内固定网数据传送业务是什么&#xff1f; 固定网国内数据传送业务是指互联网数据传送业务以外的&#xff0c;在固定网中以有线方式提供的国内端到端数据传送业务。主要包括基于IP承载网、ATM网、X.25分组交换网、DDN网、帧中继网络的数据传送业务等。该业务属于A2类基础…

数字源表表征及测试纳米材料高温原位方案

01/纳米材料电学性能的表征和分析/ 与传统的材料相比&#xff0c;纳米材料具有原子级厚度、表面平整无悬空键、载流子迁移率好等优点&#xff0c;其导电性能很大程度依赖于材料本身的带隙、掺杂浓度和载流子迁移率。同样的掺杂浓度下&#xff0c;迁移率越大&#xff0c;电阻率…

计算机网络--网络层

一、网络层的服务和功能 网络层主要为应用层提供端对端的数据传输服务 网络层接受运输层的报文段&#xff0c;添加自己的首部&#xff0c;形成网络层分组。分组是网络层的传输单元。网络层分组在各个站点的网络层之间传输&#xff0c;最终到达接收方的网络层。接收方网络层将运…

nginx SSI(Server Side Include)服务端包含 合并拼装静态内容

一、什么是SSI 在被传送给浏览器之前&#xff0c;服务器会对 HTML 文档进行完全地读取、分析以及修改&#xff0c;使用SSI指令将文本、图片或代码信息包含到网页中。对于整个页面可以拆分成多个模块&#xff0c;通过SSI指令将几个模块拼接成一个完整的页面&#xff0c;当有内容…

大模型在软件测试领域的应用场景有哪些?_大模型在测试领域应用

在数字化转型的大背景下&#xff0c;在软件定义一切的趋势下&#xff0c;软件测试人员需要接触和理解的信息越来越多&#xff0c;并呈现加速增长的态势。需求越来越大&#xff0c;交付周期越来越短&#xff0c;受制于体力和能力限制&#xff0c;测试人员的效率和质量难以同步提…

基于模式识别的垃圾分类系统-计算机毕业设计源码96151

摘 要 随着城市化进程的加速和人口的不断增长&#xff0c;垃圾管理和环境保护成为了全球面临的重要挑战之一。垃圾分类作为一种可行的解决方案&#xff0c;旨在减少垃圾的数量、降低环境污染&#xff0c;并促进资源的回收与再利用。 本文旨在设计并开发一个垃圾分类系统。该系统…

电工电子革新风暴:在线电路仿真软件重塑行业格局

随着科技的不断进步&#xff0c;电工电子行业正迎来一场由在线电路仿真软件引领的革新风暴。这些功能强大的软件工具不仅极大地提高了电路设计的效率&#xff0c;更为整个行业带来了前所未有的冲击和机遇。 仿真软件&#xff1a;电工电子行业的“隐形推手” 在线电路仿真软件…

代码随想录算法训练营第42天| 198.打家劫舍、213.打家劫舍II 337.打家劫舍III、 337.打家劫舍III

198.打家劫舍 题目链接&#xff1a;198.打家劫舍 文档讲解&#xff1a;代码随想录 状态&#xff1a;不会 记忆化搜索思路&#xff1a; 可以从最后一间房子开始&#xff0c;每次面对一个房子要考虑打劫还是不打劫&#xff0c;如果打劫了就从它的下下个房子开始打劫&#xff0c;在…

idea Git操作

1、代码拉取&#xff08;左上角&#xff09; 或 2、代码push&#xff08;左上角&#xff09; 3、切换分支&#xff08;右下角&#xff09; 4、分支管理 5、当前分支和某一个分支对比差异 6、当前分支某一个提交需要恢复成提交前状态&#xff08;revert&#xff09; 7、其他分…

Python处理浮点数的实用技巧

更多Python学习内容&#xff1a;ipengtao.com 四舍五入是一种常见的数学操作&#xff0c;它用于将数字舍入到指定的精度。Python 提供了多种方法来实现四舍五入操作&#xff0c;从基本的 round 函数到高级的 decimal 模块&#xff0c;满足不同的需求。本文将详细介绍这些方法&a…

Profibus DP主站转Modbus网关连接伺服与电机通讯

在工业自动化领域&#xff0c;将Profibus DP主站转Modbus网关&#xff08;XD-MDPBM20&#xff09;用于连接伺服与电机通讯是一种常见且重要的应用方式。当使用Profibus DP主站转Modbus网关&#xff08;XD-MDPBM20&#xff09;连接伺服与电机进行通讯时&#xff0c;可以参考以下…

使用代理,在Mapper层面统一封装VO、Entity 之间的转换逻辑

无聊看看开源项目&#xff0c;无意间看到里面的业务代码用到了BaseMapperPlus&#xff0c;于是点进去发现里面封装了Vo、Entity 之间的转换逻辑。想着自己平时都是手动的进行 copy 转换来着。于是本地进行验证了一番&#xff0c;发现还挺好用的&#xff0c;懒人必备。但是前提是…

MySQL 9.0 悄悄上线,支持面向AI的向量数据库

MySQL狂热粉丝群已经发现MySQL官网上MySQL9.0这两天悄然上线&#xff0c;已经可以下载体验了&#xff0c;目前被定义为创新版本&#xff08;Innovation&#xff09;。 下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/ 支持主流的操作系统&#xff0c;安装后可以直…