TypeScript---class类型

一.简介

TypeScript 完全支持 ES2015 中引入的 class 关键字。

与其他 JavaScript 语言功能一样,TypeScript 添加了类型注释和其他语法,以允许你表达类和其他类型之间的关系。

1.字段

(1).在申明时同时给出类型
class Person {name: string;age: number;
}

(2).申明时不给出类型

如果不给出类型,那么typescript会自动推断为any类型的数据

class Person {name; // any类型age; // any类型
}

(3).声明时给出初值

typescript会自动推断出来数据的类型是什么,比如下面的就会推断出来数据的类型为string与number

class Person {name = "寻谬~流光"; // stringage = 30; // number
}

(4).打开了TypeScript 的配置项strictPropertyInitialization

只要打开,就会检查属性是否设置了初值,如果没有就报错。

如果你打开了这个设置,但是某些情况下,不是在声明时赋值或在构造方法里面赋值,为了防止这个设置报错,可以使用非空断言。

class person {name!: string;age!: number;
}

属性名后面添加了感叹号,表示这两个属性肯定不会为空,所以 TypeScript 就不报错了

2.readonly 修饰符

属性名前面加上 readonly 修饰符,就表示该属性是只读的。实例对象不能修改这个属性。

  1. 属性前面有 readonly 修饰符,实例对象修改这个属性就会报错。
  2. 构造方法内部可以设置只读属性的初值
  3. 构造方法可以修改只读属性的值
class Person {readonly name = "寻谬~流光";readonly age!: number;// 哎构造函数内部可以自由修改readonly属性,不管是已经赋值了的,或者是没有赋值的数据类型constructor(age: number) {this.age = age;this.age = 20;}
}const p = new Person(18);
console.log(p.name); // 寻谬~流光
console.log(p.age); // 20p.age = 25; // 编译器报错, 不能对readonly属性重新赋值

3.构造器

constructor 方法是 class 的一个特殊方法,用于创建和初始化该类的对象实例。

类构造函数与函数非常相似。你可以添加带有类型注释、默认值和重载的参数

class Person {name = "寻谬~流光";age!: number;//通过给参数设置默认值,实现类似重载的效果。constructor(age: number = 18, name: string = "寻谬~流光") {this.age = age;this.name = name;}
}let p1 = new Person();
let p2 = new Person(20, "寻觅~流光");
let p3 = new Person(undefined, "你好");console.log(p1); // Person { name: '寻谬~流光', age: 18 }
console.log(p2); // Person { name: '寻觅~流光', age: 20 }
console.log(p3); // Person { name: '你好', age: 18 }

4.方法

类上的函数属性称为方法。

类的方法就是普通函数,类型声明方式与函数一致。

class Person {name = "寻谬~流光";age!: number;constructor(age: number = 18, name: string = "寻谬~流光") {this.age = age;this.name = name;}// 不添加函数返回值的类型,typescript会自动推导出来这个函数返回的数据类型((method) Person.add_age(num: number): number)add_age(num: number) {this.age += num;return this.age;}// 添加类型注释low_age(num: number = 1): number {this.age -= num;return this.age;}
}

5.获取器/设置器

存取器(accessor)是特殊的类方法,包括取值器(getter)和存值器(setter)两种方法。

它们用于读写某个属性,取值器用来读取属性,存值器用来写入属性。

class C {_name = "";get name() {return this._name;}set name(value) {this._name = value;}
}

上面示例中,get name()是取值器,其中get是关键词,name是属性名。外部读取name属性时,实例对象会自动调用这个方法,该方法的返回值就是name属性的值。

set name()是存值器,其中set是关键词,name是属性名。外部写入name属性时,实例对象会自动调用这个方法,并将所赋的值作为函数参数传入。

(1).如果某个属性只有get方法,没有set方法,那么该属性自动成为只读属性。
class Person {_name: string;_age: number;constructor(name: string, age: number) {(this._name = name), (this._age = age);}// name为只读属性get name(): String {return this._name + "___ABC";}
}
const p = new Person("Tom", 20);
console.log(p.name); // Tom___ABCp.name = "Jerry"; // 报错,不能修改只读属性

(2).set方法的参数类型,必须兼容get方法的返回值类型,否则报错。
class Person {_name: string;_age: number;constructor(name: string, age: number) {(this._name = name), (this._age = age);}get name(): string {return this._name + "___ABC";}// 正确写法// set name(value: string) {//   this._name = value;// }// 报错set name(value: number) {this._name = value;}
}

(3).get方法与set方法的可访问性必须一致,要么都为公开方法,要么都为私有方法。

正确写法:

class Person {_name: string;_age: number;constructor(name: string, age: number) {(this._name = name), (this._age = age);}private get name(): string {return this._name + "___ABC";}private set name(value: string) {this._name = value;}
}

错误写法:

class Person {_name: string;_age: number;constructor(name: string, age: number) {(this._name = name), (this._age = age);}private get name(): string {return this._name + "___ABC";}// Get 访问器必须至少具有与 Setter 相同的可访问性public set name(value: string) {this._name = value;}
}

6.索引签名

类可以声明索引签名;这些工作与 其他对象类型的索引签名 相同:

类允许定义属性索引。

class MyClass {[s: string]: boolean | ((s: string) => boolean);get(s: string) {return this[s] as boolean;}
}

上面示例中,[s:string]表示所有属性名类型为字符串的属性,它们的属性值要么是布尔值,要么是返回布尔值的函数。

注意,由于类的方法是一种特殊属性(属性值为函数的属性),所以属性索引的类型定义也涵盖了方法。如果一个对象同时定义了属性索引和方法,那么前者必须包含后者的类型。

class MyClass {[s: string]: boolean;f() {// 报错return true;}
}

上面示例中,属性索引的类型里面不包括方法,导致后面的方法f()定义直接报错。正确的写法是下面这样。

class MyClass {[s: string]: boolean | (() => boolean);f() {return true;}
}

属性存取器等同于方法,也必须包括在属性索引里面。

class MyClass {[s: string]: boolean;get(s: string) {// 报错return this[s] as boolean;}
}

上面示例中,属性索引没有给出方法的类型,导致get()方法报错。

二.类的 interface 接口

1.implements 关键字

interface 接口或 type 别名,可以用对象的形式,为 class 指定一组检查条件。然后,类使用 implements 关键字,表示当前类满足这些外部类型条件的限制。

interface Person {name: string;age: number;
}// 或者这种写法
// type Person = {
//   name: string;
//   age: number;
// };class Student implements Person {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}
}

 你可以使用 implements 子句来检查一个类是否满足特定的 interface。如果一个类未能正确实现它,则会触发错误:

interface Pingable {ping(): void;
}class Sonar implements Pingable {ping() {console.log("ping!");}
}class Ball implements Pingable {pong() {console.log("pong!");}
}

implements关键字后面,不仅可以是接口,也可以是另一个类。这时,后面的类将被当作接口。

class Person {name: string;age: number;add: (value: number) => number;
}// 实现接口
class Student implements Person {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}add(value: number) {this.age += value;return this.age;}
}

注意,interface 描述的是类的对外接口,也就是实例的公开属性和公开方法,不能定义私有的属性和方法。这是因为 TypeScript 设计者认为,私有属性是类的内部实现,接口作为模板,不应该涉及类的内部代码写法。

2.实现多个接口

类可以实现多个接口(其实是接受多重限制),每个接口之间使用逗号分隔。

interface student {//...
}
interface teacher {// ...
}// 继承多个接口
class class_people implements student, teacher {// ...
}

3.类与接口的合并

TypeScript 不允许两个同名的类,但是如果一个类和一个接口同名,那么接口会被合并进类。

interface person {name: string;
}
class person {age: number;adress: string;id: number;
}const p: person = {name: "Tom",age: 25,adress: "China",id: 123456,
};console.log(p.name); // Tom

就比如上

定义了person的接口与person的类,接口定义的会被合并到class的类型定义中去

三.类继承

1.extends 从句

类可能来自基类。派生类具有其基类的所有属性和方法,还可以定义额外的成员。

class father {name: string;age: number;
}
class son extends father {name: string;age: number;adress: string;
}
let s = new son();
s.name = "Tom";
s.age = 20;
s.adress = "China";
console.log(s);
  • super(name, age):在子类构造函数中,必须先调用父类的构造函数,才能使用 this
  • 如果子类重写了父类方法,也可以在方法中用 super.方法名() 调用父类的方法。

2.super语句

super 语句用于在子类中调用父类的构造函数或父类的方法。

class Father {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}
}class Son extends Father {adress: string;constructor(name: string, age: number, adress: string) {super(name, age); // 调用父类构造函数this.adress = adress;}
}const s = new Son("Tom", 20, "China");

3.override语句

在 TypeScript 中,override 关键字用于明确表示子类正在重写父类的成员方法或属性。这样可以让编译器检查你是否真的在重写父类已有的方法,防止拼写错误或父类没有该方法时出错。

class Father {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}sayHello() {console.log(`Hello, I am ${this.name}`);}
}class Son extends Father {adress: string;constructor(name: string, age: number, adress: string) {super(name, age); // 调用父类构造函数this.adress = adress;}// 重写父类方法override sayHello() {super.sayHello(); // 可选:调用父类方法console.log(`I live in ${this.adress}`);}
}const s = new Son("Tom", 20, "China");
s.sayHello();
// 输出:
// Hello, I am Tom
// I live in China
  • override 只能用于重写父类已有的方法或属性。
  • 如果父类没有 sayHello 方法,写 override sayHello() 会报错,防止误写。
  • 推荐在所有重写父类成员时加上 override,代码更规范、安全。

四.成员可见性

类的内部成员的外部可访问性,由三个可访问性修饰符(access modifiers)控制:publicprivateprotected

这三个修饰符的位置,都写在属性或方法的最前面。

1.public

(1). 基本用法

public修饰符表示这是公开成员,外部可以自由访问。

正常情况下,除非为了醒目和代码可读性,public都是省略不写的。

class Person {public name: string;     // 显式声明为publicage: number;             // 隐式public(默认)public constructor(name: string, age: number) {this.name = name;this.age = age;}public greet() {        // 方法默认也是publicreturn `Hello, I'm ${this.name}`;}
}const person = new Person("Alice", 30);
console.log(person.name);  // 合法:外部可访问public成员
person.greet();            // 合法

2.protected

(1). 基本用法

protected修饰符表示该成员是保护成员,只能在类的内部使用该成员,实例无法使用该成员,但是子类内部可以使用。

class Animal {protected name: string;constructor(name: string) {this.name = name;}protected move(distance: number) {console.log(`${this.name} moved ${distance}m.`);}
}class Dog extends Animal {constructor(name: string) {super(name);}bark() {console.log(`${this.name} barks!`); // 合法:子类可访问protected成员this.move(5);                      // 合法:子类可调用protected方法}
}const dog = new Dog("Buddy");
// console.log(dog.name); // 错误:实例无法访问protected成员
// dog.move(10);          // 错误
dog.bark();              // 合法

(2).子类不仅可以拿到父类的保护成员,还可以定义同名成员。
class Vehicle {protected speed: number = 0;protected accelerate(value: number) {this.speed += value;}
}class Car extends Vehicle {protected speed: number = 10; // 子类可以定义同名protected成员override accelerate(value: number) {this.speed += value * 2;   // 子类可以重写protected方法}
}

(3).在类的外部,实例对象不能读取保护成员,但是在类的内部可以。

3.private

(1). 基本用法

private修饰符表示私有成员,只能用在当前类的内部,类的实例和子类都不能使用该成员。

class BankAccount {private balance: number = 0;constructor(initialDeposit: number) {this.balance = initialDeposit;}public deposit(amount: number) {this.balance += amount; // 合法:类内部可访问private成员}public getBalance() {return this.balance;    // 合法}
}const account = new BankAccount(1000);
// console.log(account.balance); // 错误:无法访问private成员
account.deposit(500);
console.log(account.getBalance()); // 合法:通过public方法访问

(2).子类不能定义父类私有成员的同名成员。
class Base {private code: string = "123";
}class Derived extends Base {// private code: number = 456; // 错误:不能重定义父类私有成员
}

(3).如果在类的内部,当前类的实例可以获取私有成员。

4.实例属性的简写形式

在构造函数参数前加上 publicprotected 或 private,TypeScript 会自动为你声明并初始化同名实例属性。

这种写法更简洁,常用于数据类或 DTO(数据传输对象)。

这样可以让代码更简洁、易读。

class Config {constructor(public apiKey: string,public timeout: number = 5000,private debug?: boolean) {}
}const config = new Config("123-456");
console.log(config.timeout); // 输出: 5000 (默认值)

五.静态成员

类的内部可以使用static关键字,定义静态成员。

静态成员的特点:

  1. 包括静态属性和静态方法,只能通过类名直接访问,无法通过实例调用。
  2. 类加载时创建,仅一份
  3. 子类可以继承父类的静态成员,也可以重写静态方法
class Person {static value = 1;constructor(public name: string) {}log_value() {console.log(Person.value);}add_value(num: number) {Person.value += num;}
}// 只可以通过类名直接访问到静态属性和方法
// 这里静态方法同样如此,就不写了
console.log(Person.value);let p: Person = new Person("Tom");
let p2: Person = new Person("Jerry");p.log_value(); // 1
p2.log_value(); // 1p.add_value(2);p.log_value(); // 3
p2.log_value(); // 3p2.add_value(3);p.log_value(); // 6
p2.log_value(); // 6

六.抽象类,抽象成员

TypeScript 允许在类的定义前面,加上关键字abstract,表示该类不能被实例化,只能当作其他类的模板。这种类就叫做“抽象类”(abastract class)。

1.抽象类只能当作基类使用,用来在它的基础上定义子类。

不能实例化抽象类

abstract class Animal {constructor(public name: string, public age: number) {}
}// const Animal_1 = new Animal("Animal", 1); // 错误! 不能实例化抽象类class Dog extends Animal {constructor(name: string, age: number, public breed: string) {super(name, age); // 实现构造函数}bark() {console.log(`${this.name} is barking.`);}
}

2.抽象类的子类也可以是抽象类,也就是说,抽象类可以继承其他抽象类。

abstract class Animal {constructor(public name: string, public age: number) {}
}abstract class Dog extends Animal {constructor(name: string, age: number, public breed: string) {super(name, age);}sound(): void {console.log("W-T-F !");}
}class Labrador extends Dog {constructor(name: string, age: number) {super(name, age, "Labrador");}bark(): void {console.log("Woof, woof!");}
}const myDog = new Labrador("Buddy", 3);
myDog.sound(); // 输出: W-T-F !

3.抽象成员

如果抽象类的属性前面加上abstract,就表明子类必须给出该方法的实现。

abstract class Animal {constructor(public name: string, public age: number) {}abstract makeSound(): void; // 抽象成员函数
}class Dog extends Animal {// 实现抽象成员函数makeSound() {console.log("w t f!");}
}

(1)抽象成员只能存在于抽象类,不能存在于普通类。

(2)抽象成员不能有具体实现的代码。也就是说,已经实现好的成员前面不能加abstract关键字。

(3)抽象成员前也不能有private修饰符,否则无法在子类中实现该成员。

(4)一个子类最多只能继承一个抽象类。

总之,抽象类的作用是,确保各种相关的子类都拥有跟基类相同的接口,可以看作是模板。其中的抽象成员都是必须由子类实现的成员,非抽象成员则表示基类已经实现的、由所有子类共享的成员。

七.this 问题

在类中,this 始终指向当前实例对象,但这个指向会受到调用方式的影响。

  • 当通过 实例.方法() 调用时,this 正常指向实例;
  • 当方法被单独提取(如赋值给变量、作为回调)时,this 会丢失指向(变成 undefined 或全局对象)。

这是因为类的方法默认定义在原型上,调用时需要依赖调用者来确定 this 的指向(即 “谁调用,this 指向谁”)。

1.常见的this场景问题

(1).方法作为回调函数时,this 丢失

原因callback 只是一个函数引用,调用时没有 “调用者”,this 无法指向 user 实例。

class User {name: string = "Alice";sayHi() {console.log(`Hi, I'm ${this.name}`); // 这里的 this 会在回调中丢失!}
}const user = new User();
// 直接调用:this 指向 user 实例(正常)
user.sayHi(); // 输出:Hi, I'm Alice// 将方法提取为回调函数
const callback = user.sayHi; 
// 单独调用时,this 指向 undefined(严格模式下)
callback(); // 报错:Cannot read property 'name' of undefined

(2).事件监听中的 this 丢失

原因:DOM 事件回调中,this 默认指向触发事件的 DOM 元素,覆盖了类实例的 this

class Button {label: string = "Click me";onClick() {console.log(`Clicked ${this.label}`); // 事件触发时,this 指向触发事件的 DOM 元素,而非实例}
}const btn = new Button();
// 给按钮绑定点击事件(假设页面有个 id 为 "btn" 的按钮)
document.getElementById("btn")?.addEventListener("click", btn.onClick);// 当点击按钮时:
// 输出:Clicked undefined(因为 this 指向按钮 DOM 元素,而非 Button 实例)

(3).箭头函数与普通方法的 this 差异

原因:箭头函数没有自己的 this,它的 this 是定义时捕获的上下文(此处即类实例)。

class Test {value: number = 10;// 普通方法:this 依赖调用者normalMethod() {console.log(this.value);}// 箭头函数方法:this 固定指向实例arrowMethod = () => {console.log(this.value);};
}const test = new Test();
const normal = test.normalMethod;
const arrow = test.arrowMethod;normal(); // 报错:this 丢失
arrow();  // 正常输出:10(this 始终指向 test 实例)

2.解决 this 指向问题的 3 种方案

(1).在构造函数中绑定 this(最常用)

通过 this.方法 = this.方法.bind(this) 强制绑定 this 到实例:

class User {name: string = "Alice";constructor() {// 绑定 this 到当前实例this.sayHi = this.sayHi.bind(this);}sayHi() {console.log(`Hi, I'm ${this.name}`);}
}const user = new User();
const callback = user.sayHi;
callback(); // 正常输出:Hi, I'm Alice(this 已绑定)

(2).使用箭头函数定义方法(简洁)

直接将方法定义为箭头函数,利用箭头函数的 this 特性固定指向:

class Button {label: string = "Click me";// 箭头函数方法:this 永远指向实例onClick = () => {console.log(`Clicked ${this.label}`);};
}const btn = new Button();
document.getElementById("btn")?.addEventListener("click", btn.onClick);
// 点击时输出:Clicked Click me(this 正确指向 Button 实例)

(3).调用时通过 call/apply 指定 this

在调用方法时,用 call 或 apply 手动指定 this

class User {name: string = "Bob";sayHi() {console.log(`Hi, I'm ${this.name}`);}
}const user = new User();
const callback = user.sayHi;// 调用时用 call 绑定 this
callback.call(user); // 输出:Hi, I'm Bob

八.泛型类

类也可以写成泛型,使用类型参数。关于泛型的详细介绍

class person<T> {name: T;age: number;constructor(name: T, age: number) {this.name = name;this.age = age;}
}let p1: person<string> = new person("Tom", 25);
console.log(p1.name); // output: Tom

注意,静态成员不能使用泛型的类型参数。

下一篇:TypeScript---泛型

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

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

相关文章

vue3中实现echarts打印功能

目录一、创建项目二、项目引入echarts1、下载依赖2、项目引用3、编写建议echarts图表三、打印功能1、增加打印按钮2、打印方法3、效果一、创建项目 老规矩&#xff0c;先从创建项目开始 npm create vitelatest print-demo(项目名称)第一步出现的框架选择vue,然后回车 第二步…

今日行情明日机会——20250711

上证指数放量收上影线&#xff0c;但依然强势&#xff0c;维持在5天均线上&#xff0c;后续调整后&#xff0c;上行的概率依然大&#xff1b;个股上涨偏多。深证指数缓慢上涨&#xff0c;已经突破下跌趋势线&#xff0c;目前依旧沿着5日线上行&#xff0c;后市依然值得期待。20…

「日拱一码」024 机器学习——防止过拟合

目录 数据层面 数据增强 数据正则化 ​数据采样 模型结构层面 简化模型 添加正则化层 早停法&#xff08;Early Stopping&#xff09; 训练过程层面 使用交叉验证 使用集成学习 调整学习率 防止过拟合是机器学习中一个非常重要的问题&#xff0c;它可以帮助模型在新…

持有对象-泛型和类型安全的容器

我们需要管理一批对象序列&#xff0c;但是又对实际运行的时候的对象类型和对象序列长度不确定的时候&#xff0c;用简单的对象引用无法满足&#xff0c;java有ArrayList,Map,Set等这些容器类提供&#xff0c;这些都实现了Collections接口&#xff0c;所以都属于Collections类。…

《财税企业经营管理秘籍(一):行业适配的获客方式》

在财税服务这片竞争激烈的红海中&#xff0c;客户资源如同氧气——没有它&#xff0c;企业寸步难行。然而残酷的现实是&#xff0c;许多财税企业正深陷“获客泥潭”&#xff1a;投入巨大精力与成本&#xff0c;换来的却是转化渺茫、增长停滞的困境。高质量线索&#xff0c;已成…

使用tensorflow的多项式回归的例子(一)

多项式回归例1%matplotlib inlineimport tensorflow as tfimport numpy as npimport matplotlib.pyplot as plttrX np.linspace(-1, 1, 101)num_coeffs 6trY_coeffs [1, 2, 3, 4, 5, 6]trY 0for i in range(num_coeffs):trY trY_coeffs[i] * np.power(trX, i)trY np.rand…

STM32F103C8T6基于HAL库驱动NB-IoT模块BC26通信详 解

一、引言&#xff1a; NB-IoT技术与应用场景NB-IoT&#xff08; Narrow Band Internet of Things &#xff09;作为低功耗广域网&#xff08; LPWAN &#xff09;的核心技术&#xff0c;以其广覆 盖、低功耗、大连接、低成本的特性&#xff0c;广泛应用于智能表计、环境监测、…

iOS 性能测试工具全流程:主流工具实战对比与适用场景

在iOS开发中&#xff0c;性能优化往往被安排到开发后期&#xff0c;甚至上线前才临时补救。但性能瓶颈通常是架构设计、资源加载、动画机制等多方面共同作用的结果&#xff0c;仅凭肉眼感知和log输出&#xff0c;难以精准定位。 一套合适的性能测试工具组合&#xff0c;不仅能帮…

目标检测:视觉系统中的CNN-Transformer融合网络

一、背景 无人机&#xff08;UAVs&#xff09;在城市自动巡逻中发挥着重要作用&#xff0c;但它们在图像识别方面面临挑战&#xff0c;尤其是小目标检测和目标遮挡问题。此外&#xff0c;无人机的高速飞行要求检测系统具备实时处理能力。 为解决这些问题&#xff0c;我们提出了…

揭示宇宙的隐藏对称性:群论-AI云计算拓展核心内容

通过利用云计算&#xff0c;借助群论对宇宙对称性的探索&#xff0c;从离散群和李群等基础概念&#xff0c;逐步深入到量子力学和更高自旋系统中的高级应用。 对称性远不止是美学上的吸引力&#xff1b;它是编织在宇宙结构中的一个基本原则。从雪花的复杂图案到控制粒子的基本定…

前端项目vue3项目集成eslint@9.x跟prettier

tips: 这些涉及编辑器的修改不一定能及时生效&#xff0c;如果没有生效&#xff0c;可以试试重启编辑器窗口 编辑器集成 我的编辑器是vscode&#xff0c;需要安装这两个编辑器插件eslint prettier我这个配置主要是通过eslint提供的配置cli命令生成&#xff0c;在里面加入了对pr…

登录超时问题的排查方法与预防经验分享

​​一、排查方法​​​​检查网络连接​​确保网络稳定&#xff0c;尝试重启路由器或切换网络&#xff08;如从WiFi切换到移动数据&#xff09;。使用命令&#xff08;如 ping 或 traceroute&#xff09;测试网络连通性&#xff0c;排查是否存在丢包或高延迟。​​验证服务端状…

uniapp,Anroid10+版本如何保存图片并删除

Android 10系统开始 进一步增强了平台功能&#xff0c;为外部存储设备上的应用和用户数据提供了更好的保护。作为这项工作的一部分&#xff0c;平台引入了进一步的改进&#xff0c;以简化向分区存储的转换。 为了让用户更好地控制自己的文件&#xff0c;保护用户隐私数据&#…

Jenkins Pipeline 语法

Pipeline 简介 Jenkins2.x 的核心是使用 pipeline 来构建项目,也就是流水线,将 Jenkins1.0 版本中基于表单的配置信息比如 JDK/SVN 以及参数的配置都转变成了代码,即 pipeline as Code。 传统的表单方式有以下缺点: 需要大量的 web 表单交互,有时候需要进行很多次的切换…

搭建渗透测试环境

一、基于docker搭建靶场 #此步骤需要科学上网 #从软件源中下载 docker.io 和 docker -compose 软件包及其依赖项。 sudo apt-get install docker.io docker-compose #查看docker版本 docker -v #查看docker信息 docker info #重启docker服务 sudo systemctl daemon-reload sudo…

(一)OpenCV——噪声去除(降噪)

高斯滤波器&#xff08;针对高斯噪声&#xff09; 高斯噪声是指它的概率密度函数服从高斯分布&#xff08;即正态分布&#xff09;的一类噪声。常见的高斯噪声包括起伏噪声、宇宙噪声、热噪声和散粒噪声等等。 高斯滤波(Gaussian filter) 包含许多种&#xff0c;包括低通、带…

百度开源文心 4.5 系列开源大模型 GitCode 本地化部署,硅基流动:文心 vs. DeepSeek vs. Qwen 3.0 深度测评

百度开源文心 4.5 系列开源大模型 GitCode 本地化部署&#xff0c;硅基流动&#xff1a;文心 vs. DeepSeek vs. Qwen 3.0 深度测评 文章目录百度开源文心 4.5 系列开源大模型 GitCode 本地化部署&#xff0c;硅基流动&#xff1a;文心 vs. DeepSeek vs. Qwen 3.0 深度测评背景百…

「日拱一码」022 机器学习——数据划分

目录 基于单次随机划分的方法 普通单次随机划分&#xff08;train_test_split&#xff09; 分层单次随机划分(使用 train_test_split 的 stratify 参数) 基于多次随机划分的方法 普通多次随机划分(ShuffleSplit) 分层多次随机划分&#xff08;StratifiedShuffleSplit…

lora网关

所需配置的引脚&#xff0c;SPI传输&#xff0c;PG13复位&#xff08;输出引脚&#xff0c;推挽输出&#xff09;&#xff0c;PE2忙碌&#xff08;输入引脚&#xff0c;浮空输入&#xff09;PE6PE5输出。若利用延时处理按键消抖&#xff0c;hal库里用systick中断实现延时&#…

5G IMS注册关键一步:UE如何通过ePCO获取P-CSCF地址

看似简单的P-CSCF地址传递,背后是5G核心网控制面与用户面的精密协作。ePCO作为高效的信令载体,承载着IMS业务触达的第一把钥匙。 在5G网络中建立IMS PDN连接时,UE(用户设备)获取P-CSCF(Proxy-Call Session Control Function)地址是IMS业务(如VoLTE、VoNR)成功注册和运…