TypeScript 基础类型与类型声明

news2024/11/17 0:17:25

前言

在 JavaScript 中,变量是没有类型的,变量的值的类型是在运行时确定的,这被称为动态类型
这意味着可以在不同的时间将不同类型的值赋给同一个变量,并且 JavaScript 会在运行时根据当前赋给变量的值来确定其类型。
示例:

let a;   // 声明一个变量 a 
a = 10;  // 此时 a 的类型被确定为数字类型
a = "hello JavaScript"; // 现在 a 的类型变为字符串类型

a 的类型随着每次赋值而改变。
JavaScript 会在运行时根据实际赋给变量的值来自动调整和处理其类型。这种动态类型的特性使得 JavaScript 非常灵活,但也可能导致一些难以察觉的错误,因为类型的变化可能会在不经意间发生。

例如,想要一个变量是数字并进行数学运算,但它在运行时被意外地赋值为字符串,就会出错。

let a = 10;
let b = 5;
console.log(a + b); // 15
// 假如经历了一系列逻辑操作,需要重新对 b 赋值 并计算结果
b = "5";
console.log(a + b);  // "105",假如在别的地方要使用这个结果,会导致难以排查的错误。

JavaScript是动态类型语言,对类型的检查和约束相对较弱。

TypeScript 是 JavaScript 的超集,它支持与JavaScript几乎相同的数据类型,在 JavaScript 的基础上增加了静态类型系统。这意味着在 TypeScript 中,开发者需要在编写代码时,可以选择添加类型注释来明确指定变量、函数参数、函数返回值等的类型。

注意:TypeScript 的类型注释将始终位于被输入的内容之后。

基础类型

string:字符串类型。

// 声明一个变量 str,同时指定 str 的类型为 string
let str: string;
// str 的类型设置为 string,从此以后,str 的值只能是 字符串类型
str = "Hello"; // 字符串类型
str = 123; // 编译错误: Type 'number' is not assignable to type 'string'.

在编写代码时,编辑器报错:不能将类型“number”分配给类型“string”。
因为变量str的类型是string

可以使用模版字符串

let name: string = `张三`;
let desc: string = `我的名字是 ${name}`;

number:数字类型。

数字类型不分intfloat,全是number

let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744;

除了支持十进制和十六进制字面量,TypeScript还支持ECMAScript 2015中引入的二进制和八进制字面量。

boolean:布尔类型。

布尔类型只有两个值true/ false

let isDone: boolean = false;

始终使用stringnumberboolean来表示类型。

数组类型

TypeScript有两种方式可以定义数组。

  1. 在基础数据类型后面接上 [],表示由此类型元素组成的一个数组:
let list1: number[] = [1, 2, 3];  // 数字数组,数组的每个元素都是number类型
let list2: string[] = ["list1", "list2"]; // 字符串数组,数组的每个元素都是string类型
let list3: boolean[] = [true, false, true]; // 布尔数组,数组的每个元素都是boolean类型

let arr: string[][] = [["a", "b"], ["c", "d"]]; // 声明一个二维字符串数组。
  1. 使用数组泛型,Array<元素类型>
let list1: Array<number> = [1, 2, 3];
let list2: Array<string> = ["list1", "list2"];
let list3: Array<boolean> = [true, false, true];

元组 Tuple

TypeScript 中的元组(Tuple)是一种特殊的数组类型。
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。

特点:

  1. 固定的元素数量和类型顺序
    • 元组中的元素数量是明确的,并且每个位置的元素类型是固定的。
  2. 混合类型
    • 可以在一个元组中包含不同类型的元素。

示例:

// 定义一个包含字符串、数字和布尔值的元组
let myTuple: [string, number] = ['Hello', 42];
// 语句没有报错,why?
myTuple.push("为什么这句不报错?"); 
// 访问元组中的元素,通过索引
console.log(myTuple[0]);  // 'Hello'
console.log(myTuple[1]);  // 42
// 错误:Type 'string' is not assignable to type 'number'.(不能将类型“string”分配给类型“number”。)
myTuple[1] = 'not a number';  // 编译错误:Type 'string' is not assignable to type 'number'.

// 错误:Type 'true' is not assignable to type 'undefined'.(不能将类型“true”分配给类型“undefined”。)
// 错误:Tuple type '[string, number]' of length '2' has no element at index '2'.(长度为 "2" 的元组类型 "[string, number]" 在索引 "2" 处没有元素。)
myTuple[2] = true; 

// 错误:Argument of type 'boolean' is not assignable to parameter of type 'string | number'.(类型“boolean”的参数不能赋给类型“string | number”的参数。)
myTuple.push(true);


// 语句没有报错,why?
// myTuple.push("world"); 

TypeScript 的元组和数组的区别:

  • 元组:具有固定数量的元素,且每个元素的类型是明确且固定的。元组对每个位置的元素类型有严格的约束。
  • 数组:元素数量可以动态变化。如果指定了类型,如 number[] ,则要求所有元素都是指定的类型;如果未指定类型,元素类型可以不同(any类型)。

枚举

枚举(Enum)类型是对Java Script标准数据类型的一个补充。
枚举(Enum)是一种为一组数值赋予有意义名称的方式。
默认情况下,从 0 开始为元素编号。

enum Color {Red, Green, Blue}
console.log(Color);
// 输出以下结果
// {
//   "0": "Red",
//   "1": "Green",
//   "2": "Blue",
//   "Red": 0,
//   "Green": 1,
//   "Blue": 2
// } 

代码定义了一个名为 Color 的枚举类型,其中 Red 被初始化为 0Green1Blue2
也可以手动为枚举成员赋值:

enum Color1 {
  Red = 11,
  Green = 22,
  Blue = 33
}
console.log(Color1);
// 输出
// {
//   "11": "Red",
//   "22": "Green",
//   "33": "Blue",
//   "Red": 11,
//   "Green": 22,
//   "Blue": 33
// } 

枚举成员可以通过两种方式访问:

let c: Color = Color.Red;  // 通过枚举名.成员名
console.log(c);  // 输出 0(默认情况)

let colorName = Color[2];  // 通过枚举值获取枚举名
console.log(colorName);  // 输出 "Green"(默认情况)

Any

当一个变量被声明为 any 类型时,它可以被赋予任何类型的值,并且在对其进行操作时,TypeScript 编译器不会进行类型检查。
any 完全放弃了类型检查。

// 显式声明变量为any类型
let variable: any = 5;
variable = "Hello"; 
variable = true; 

let list: any[] = [1, true, "free"];  // list 包含了不同的类型的数据
list[1] = 66;

// 隐式声明变量为any类型
// 声明变量 并且 不指定类型, TS 解析器会自动判断变量的类型为any
let variable1;
variable1 = "Hello"; 
variable1 = true; 

在上述代码中,variablevariable1 可以被随意赋值为不同类型的值。

any 类型的变量还可以赋值给任意类型的变量:

let variable: any = 5;
variable = "Hello"; 
variable = true; 

let str : string;
str = variable;
console.log(str);  // true; TS类型检查器不会再检查 变量 str 。

通常,只有在确实无法确定变量类型或者需要与旧的 JavaScript 代码进行交互且类型难以明确时,才建议使用 any 类型。

unknown

unknown 类型表示一个值的类型是未知的。
只有 any 类型和 unknown 类型的值可以赋给 unknown 类型的变量。
unknown 类型是一种比 any 更安全的类型,对 unknown 类型的值进行操作是受到限制的。
例如,如果有一个变量 x 的类型是 unknown ,在对其进行操作之前,必须先进行类型断言或类型缩小的检查:

let x: unknown;
// 错误,不能直接对 unknown 类型的值进行操作
// x.toUpperCase(); // 报错:x 的类型是 “未知”
if (typeof x ==='string') {
  // 经过类型缩小检查后,可以进行操作
  x.toUpperCase();
}

可以对 x 进行任意赋值:

let variable: any;
let x: unknown;
x = "Hello";  // 合法,因为可以将 any 或 unknown 类型的值赋给 unknown 类型的变量
x = true;    
x = variable; // 合法,因为可以将 any 或 unknown 类型的值赋给 unknown 类型的变量

不能将 unknown 类型的变量 赋值给 除any类型外的 其他类型的变量:

let str : string;
str = x; // 不能将类型“unknown”分配给类型“string”。

let variable: any;
variable = x; // 合法,因为 any 类型可以被赋值任意类型的值

unknown 类型的主要用途是在处理可能来自不可信或动态来源的数据时,提供一种更严格的类型控制,以防止意外的类型错误。

unknown 和 any 的区别

  1. 类型安全性:
    • any 完全放弃了类型检查,可以对 any 类型的变量执行任何操作,而 TypeScript 编译器不会产生错误。
    • unknown 则更安全,对 unknown 类型的变量进行操作时,TypeScript 编译器会要求先进行类型断言或类型缩小检查,以确保操作的合法性。
  2. 可赋值性:
    • 任何类型的值都可以赋给 any 类型的变量。
      any 类型的变量可以被赋值给任意类型的变量,并关闭该变量的TypeScript 静态类型检查。
    • 只有 any 类型和 unknown 类型的值可以赋给 unknown 类型的变量。
      unknown 类型的变量不可以被赋值给 除 any 类型外 的 其他类型的变量。
  3. 操作限制:
    • 对于 any 类型的变量,可以直接调用任何方法和访问任何属性,而无需考虑其实际类型。
    • 对于 unknown 类型的变量,在没有进行类型断言或缩小检查之前,不能直接调用方法或访问属性。

Void

在 TypeScript 中,void 类型用于表示没有任何返回值的函数。
当变量被声明为 void 类型时,只能被赋值为 undefined :

let unusable: void = undefined;
let unusable1: void = null; // 报错:不能将类型“null”分配给类型“void”。

void 类型用来表示函数没有返回值的情况。当你尝试将 null 赋值给一个 void 类型的变量时,编译器会报错,因为 null 表示对象的引用,而 void 不是一个对象,它只是一个表示无返回值的特殊类型。
在这里插入图片描述
当一个函数没有返回值时,你通常会见到其返回值类型是 void

function printMsg(): void {
    console.log("This is my message");
}

function noReturn(): void {
    return 
    // return undefined
}

Null 和 Undefined

在 TypeScript 中,null的类型是nullundefined 的类型是undefined

默认情况下nullundefined是所有类型的子类型。 就是说你可以把 nullundefined赋值给其他类型的变量。

let u: undefined = undefined; // 变量类型是undefined,值是undefined
let n: null = null;  // 变量类型是null ,值是null 

let num: number = null;  // 合法,但不推荐
let str: string;
console.log(str);  // 输出 undefined

在 TypeScript 的严格空值检查模式(通过在 tsconfig.json 中设置 "strictNullChecks": true )下,对 nullundefined 的处理更加严格。例如,函数参数不能默认是 nullundefined ,除非明确指定类型为 number | nullstring | undefined 这样的联合类型。

文中所有例子都假设"strictNullChecks": false

Never

never类型表示的是那些永不存在的值的类型。

在 TypeScript 中,一般不会直接创建 never 类型的变量。因为 never 表示永远不会有值的类型。
但在某些复杂的类型推导或函数的返回类型中,可能会出现被推断为 never 类型的情况。

它通常用于以下几种情况:

  1. 函数中抛出异常或进入一个无限循环:
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
    throw new Error(message);
}
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
    while (true) {}
}

// 推断的返回值类型为never
function fail() {
    return Error("Something failed");
}

  1. 用来表示一个函数的返回值类型,当这个函数永远不会正常返回(即总是以抛出异常结束)。

例如,如果一个函数用于处理所有可能的情况,并且对于某些输入它应该抛出错误,那么其返回类型可以是 never

function exhaustiveCheck(x: string): never {
    if (x === 'a') {
        // 一些处理逻辑
    } else if (x === 'b') {
        // 一些处理逻辑
    } else {
        throw new Error('Unexpected value');
    }
}

object

在 TypeScript 中,object 类型用于表示非原始类型,除 numberstringbooleansymbolnullundefined 外的类型。

let obj: Object;
obj = { name: 'John' };  // obj 是一个对象
obj = function() {};  // obj是一个函数,函数也是对象

let arr: Object = [1, 2, 3];  // 数组是特殊的对象

在JavaScript中,几乎所有的数据类型都可以被视为对象,或者具有对象的某些特性。

基本数据类型如数字、字符串、布尔值,在 JavaScript 中都有对应的对象形式。像数字 5 对应的对象形式是 new Number(5) ,字符串 "hello" 对应的对象形式是 new String("hello") ,布尔值 true 对应的对象形式是 new Boolean(true)
函数也是对象,它们可以具有属性和方法。
数组也是一种特殊的对象。
甚至一些内置的全局对象,如 Math 、 Date 等,也提供了各种功能和方法。
示例:

function myFunction() {
  console.log('Hello!');
}
myFunction.property = 'Some value';  // 函数可以添加属性

let num = 5;
let numObj = new Number(num);  // 将数字转换为对象形式

在 TypeScript 中,直接声明一个变量的类型为 object 相对较少使用,并且通常不是最佳实践。
只是声明变量的类型为 object ,它并不能明确对象应该具有哪些具体的属性,可能会导致类型检查不够严格和代码的可读性降低。
object 类型通常不是用于简单地判断一个变量是不是一个普通的对象,而是更侧重于描述对象所具有的特定属性结构。
(大多数情况下,object 被用来限制对象中的属性,而不是限制变量的类型是不是一个对象。)

// 声明一个对象类型的变量 obj ,并且指定其属性 name 的类型为字符串
let obj: {name: string};  
obj = {}; // Error: Property 'name' is missing in type '{}' but required in type '{ name: string; }'.
// (类型 "{}" 中缺少属性 "name",但类型 "{ name: string; }" 中需要该属性。)

// 对象obj的赋值必须和obj声明的结构一模一样
obj = {name: "张三"};
obj = {name: "张三", age: 18};  // Error: Object literal may only specify known properties, and 'age' does not exist in type '{ name: string; }'.
// (对象字面量只能指定已知属性,并且“age”不在类型“{ name: string; }”中。)

属性名后面加上?,表示是可选属性:

// 这里的 ? 表示 age 属性是可选的
let obj: { name: string, age?: number };
obj = {name: "张三"};  // 合法, 因为 age 是可选属性
obj = {name: "张三", age: 18}; // 合法

假设对象obj必须要有name属性,其余属性可有可无:

let obj: { name: string, [propName: string]:any };
obj = {name: "张三", age: 18}; // 合法
obj = {name: "张三", age: 18, sex: "male"}; // 合法

// Error: Property 'name' is missing in type '{ age: number; }' but required in type '{ [propName: string]: any; name: string; }'.
obj = {age: 18}; // 不合法,因为没有 'name' 属性

// Error: Type 'number' is not assignable to type 'string'.
obj = {name: 18}; // 因为 'name' 属性不是字符串类型
  1. let obj 声明了一个变量 obj
  2. { name: string, [propName: string]:any } 定义了这个变量的类型。
    • name: string 明确指定了 obj 必须具有一个名为 name 的属性,且这个属性的值必须是字符串类型。
    • [propName: string]:any 这部分是一个索引签名。propName 是一个变量名,在这里只是表示任意属性的名称。string 表示属性名的类型是字符串。any 表示对应属性的值可以是任何类型。
      这意味着除了必须存在的 name 属性是字符串类型外,obj 还可以有任意数量的其他属性,这些属性的名称是字符串,并且值可以是任何类型。

使用object类型,可以更好的表示像Object.create这样的API。

declare function create(o: object | null): void;

declare 关键字用于声明存在一个在其他地方定义(可能是在外部模块、全局环境或其他源文件)的函数。
这段代码声明了一个名为 create 的函数,它接受一个参数 oo 的类型可以是一个对象或者 null ,并且这个函数没有返回值(void)。
调用create 函数:

create({ key: 'value' }); 
create(null); 

create(5);  // 错误,因为 5 不是对象也不是 null
create('string');  // 错误,因为 'string' 不是对象也不是 null

联合类型声明

  1. 基本用法
let value: string | number; // 表示 value 可以是字符串或者数字。
value = "hello typescript"; // 合法
value = 123; // 合法
value = [];  // 不合法
  1. 函数参数
function printValue(value: string | number) {
  if (typeof value ==='string') {
    console.log(`It's a string: ${value}`);
  } else {
    console.log(`It's a number: ${value}`);
  }
}

printValue("World");  // 合法
printValue(456);  // 合法
  1. 与对象类型相结合
interface Person {
  name: string;
  age: number;
}

interface Animal {
  species: string;
}

let entity: Person | Animal;

entity = { name: "John", age: 30 };  // 合法
entity = { species: "Dog" };        // 合法
entity = { name: "John", age: 30, species: "Dog" };  // 合法

声明了一个变量 entity ,其类型为 PersonAnimal 的联合类型,这意味着 entity 可以被赋值为符合 Person 接口结构的对象,或者符合 Animal 接口结构的对象,也可以同时符合 PersonAnimal 结构的对象。
通过联合类型的声明,使得 entity 变量能够灵活地接受不同类型但具有特定结构的对象值。

  1. 数组中的联合声明
let arr: (string | number)[];
arr = ["Hello", 123, "World", 456]; // 合法

arr = ["Hello", 123, "World", true]; // 不合法
// Error: Type 'boolean' is not assignable to type 'string | number'.

(string | number)[] 是数组的类型声明。其中 string | number 是联合类型,表示数组中的元素可以是字符串类型(string)或者数字类型(number)。

联合类型为处理可能具有多种类型的值提供了灵活性。

交叉类型声明

在 TypeScript 中,交叉类型(Intersection Type)用于将多个类型合并为一个新的类型,该新类型具有所合并类型的所有成员。
交叉类型使用 & 符号来创建。
例如,如果有两个接口 UserEmployee

interface User {
  name: string;
  age: number;
  sayYes(): void;
}

interface Employee {
  jobTitle: string;
  salary: number;
  sayNo(): void;
}

创建一个交叉类型 UserEmployee

type UserEmployee = User & Employee;

// 错误: “UserEmployee”仅表示类型,但在此处却作为值使用。
console.log(UserEmployee ); // Error: 'UserEmployee' only refers to a type, but is being used as a value here.

UserEmployee 类型的对象同时具有 UserEmployee 接口中定义的所有属性和方法:

let person: UserEmployee = {
  name: "张三",
  age: 30,
  jobTitle: "Developer",
  salary: 10000,
  sayYes() {
  	console.log('sayYes!');
  },
  sayNo() {
  	console.log('sayNo!');
  }
};

在交叉类型中,需要注意以下几点:

  1. 同名属性的类型必须兼容。如果两个接口中都有一个名为 id 的属性,但一个是字符串类型,另一个是数字类型,就会导致类型错误。
  2. 方法也会被合并,如果两个接口中有同名的方法,那么它们的实现需要保持一致,否则也会导致类型错误。
  3. 交叉类型可以用于多个接口、类型别名甚至具体的对象类型的合并。

交叉类型在一些场景中非常有用,比如需要一个对象同时满足多个不同的类型约束,或者需要将多个相关但又有所不同的类型组合在一起。

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

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

相关文章

学生管理系统之界面设计

学生管理系统之界面设计 建立工程 新建登录界面

自动气象站:高度自动化、智能化和精准化

自动气象站&#xff0c;作为科技进步的产物&#xff0c;以其高度的自动化、智能化和精准化特点&#xff0c;极大地提升了气象观测的效率和准确性。它集成了多种高精度传感器&#xff0c;能够全天候、不间断地监测温度、湿度、气压、风速、风向、降水量等关键气象要素&#xff0…

RabbitMq架构原理剖析及应用

文章目录 RabbitMQ 架构组件1. **Broker** (Broker Server)2. **Exchange**3. **Queue**4. **Producer** (消息生产者)5. **Consumer** (消息消费者)6. **Virtual Hosts** (虚拟主机) 工作流程内部原理1. **队列管理**2. **集群**3. **持久化与内存**4. **性能优化** 高级特性1…

高德地图离线版 使用高德地图api的方法

高德离线包我已经存至Gitee&#xff08;自行下载即可&#xff09;&#xff1a;高德地图离线解决方案: 高德地图离线解决方案 然因为高德地图的瓦片地图太大&#xff0c;所以要让后端部署下 前端直接调用 如果本地 直接找到瓦片图路径就可以 initMap () {const base_url "…

基于 Kafka 的经验:AutoMQ 和 MinIO 如何解决成本和弹性挑战

Apache Kafka 因其出色的设计和强大的功能而成为流式处理的事实标准。它不仅定义了现代流式处理的架构&#xff0c;而且其独特的分布式日志抽象还为实时数据流处理和分析提供了前所未有的功能。Kafka 的成功在于它能够满足高吞吐量和低延迟的数据处理需求&#xff0c;多年来&am…

(2024|ICLR,∞-Diff,无限维平滑扩散,希尔伯特空间,超分辨率,多尺度架构)具有子采样平滑状态的无限分辨率扩散

∞-Diff: Infinite Resolution Diffusion with Subsampled Mollified States 目录 0. 摘要 1. 简介 2. 生成式神经场 3. 无限维扩散模型 3.1 平滑化&#xff08;Mollificaition&#xff09; 3.2 无限维度平滑扩散 4. 参数化扩散过程 4.1 神经算子 4.2 多尺度架构 4.3…

element-plus框架+vue3+echart——后台页面

一、图表样式 图表组件&#xff1a;echarts https://echarts.apache.org/examples/zh/index.html element-plus框架&#xff1a; https://www.cwgj.xyz/zh-CN/ 1、折线图 栅格 一共24。 12代表占一半50%&#xff0c; 当页面缩小到一定程度 占整个屏幕的100%。 id"mo…

【Axure教程】拖拉拽编辑页面

低代码开发平台通常提供拖拉拽编辑页面的功能&#xff0c;使用户无需编写大量代码即可创建复杂的应用程序和页面。这种平台的特点是通过图形用户界面来进行开发&#xff0c;用户可以拖拽组件到画布上进行布局和配置。 那今天作者就教大家在Axure里怎么制作拖拉拽动态编辑页面的…

01 LVS负载均衡群集

1.1 LVS群集应用基础 群集的称呼来自于英文单词“Cluster"&#xff0c;表示一群、一串的意思&#xff0c;用在服务器领域则表示大量服务器的集合体&#xff0c;以区分于单个服务器。 1.1.1 群集技术概述 LVS&#xff08;Linux Virtual Server&#xff09;是Linux虚拟服…

linux下的线程

概念理解 linux下没有线程的概念&#xff0c;只有轻量级进程的概念&#xff0c; 有接口&#xff1a;clone() 是clone&#xff08;&#xff09;调用&#xff0c;在库中创建栈 源码解析 int clone(int (*fn)(void *), void *child_stack,int flags, void *arg, .../* pid_t *p…

【Spring】详细了解静态代理和动态代理的使用

目录 1.代理模式介绍 2. 静态代理 3.动态代理 3.1 JDK动态代理 3.2 CGLIB动态代理 4. 动态代理和静态代理的区别 1.代理模式介绍 代理模式分为动态代理和静态代理&#xff0c;目的是在不直接暴露真实对象的情况下&#xff0c;通过代理对象来间接访问真实对象&#xff0c;从…

【设计模式】设计模式之观察者模式

文章目录 观察者模式什么是观察者模式引入组成UML图代码实现1. 定义观察者接口2. 定义主题接口3. 实现具体观察者4. 实现具体被观察者5.测试 应用场景优点缺点 观察者模式 什么是观察者模式 观察者模式&#xff08;Observer Pattern&#xff09;是一种设计模式 它定义了一种…

vLLMcuda安装笔记

1. 引言 最近在部署Qwen模型时&#xff0c;文档上有提到强烈建议用vLLM来部署模型&#xff0c;按照公开的性能测试数据&#xff0c;用vLLM部署Qwen模型的文本推理速度要比transformers部署快3~4倍。带着这个好奇就开始安装尝试&#xff0c;但试下来这个安装过程并没有那么顺利…

最新个人免签约支付系统源码|PHP源码 | 码支付系统 | ThinkPHP6框架 | 开源

源码介绍&#xff1a; 这个最新的个人专用免签约支付系统源码&#xff01;是PHP源码写的哦&#xff0c;而且是用ThinkPHP6框架开发的&#xff0c;完全开源的码支付系统。 这个系统适合个人用户使用&#xff0c;作为收款的免签约解决方案。它还加入了监控端&#xff0c;可以拒…

Linux 调试追踪: trace-cmd 和 kernelshark

文章目录 1. 前言2. 概述3. trace-cmd3.1 下载3.2 交叉编译3.3 安装、运行3.3.1 trace-cmd 示范&#xff1a;抓取系统调度信息 4. kernelshark5. 参考资料 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不做任何承…

Java多线程-----定时器(Timer)及其实现

目录 一.定时器简介&#xff1a; 二.定时器的构造方法与常见方法&#xff1a; 三.定时器的模拟实现&#xff1a; 思路分析&#xff1a; 代码实现&#xff1a; 在开发中&#xff0c;我们经常需要一些周期性的操作&#xff0c;例如每隔几分钟就进行某一项操作&#xff0c;这…

【QT】常用控件-上

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 目录 &#x1f449;&#x1f3fb;QWidgetenabledgeometryrect制作上下左右按钮 window frame 的影响window titlewindowIcon代码示例: 通过 qrc 管理图片作为图标 windowOpacitycursor使用qrc自…

Python | Leetcode Python题解之第309题买卖股票的最佳时机含冷冻期

题目&#xff1a; 题解&#xff1a; class Solution:def maxProfit(self, prices: List[int]) -> int:if not prices:return 0n len(prices)f0, f1, f2 -prices[0], 0, 0for i in range(1, n):newf0 max(f0, f2 - prices[i])newf1 f0 prices[i]newf2 max(f1, f2)f0, …

【笔记】《冲击弹性波理论与应用》[2-2] 振动信号分析

1.前级硬件滤波 - 降噪 2.软件降噪 2.1 移动平滑滤波 2.1.1 移动平滑滤波的效果 2.2 经验模态分解法 2.1.1 效果 3 信号分析 除了FFT,最大熵和小波变换现在也很流行。 3.1 最大熵 3.1.1 与FFT的比对 3.2 相关性分析 3.2.1 自相关 3.2.2 互相关 3.3. 小波 非等周期信号 3…

《python语言程序设计》2018第6章第28题 掷骰子 两个色子,分别是1到6

2、3、12 玩家输 7、11玩家赢 4、5、6、8、9、10算1点&#xff0c;之后出7玩家输或者和上一次相同。def rolled(num_t):count 0still_win 0second_win 0still_lose 0second_lose 0while count < num_t:a_1 random.randint(1, 6)b_1 random.randint(1, 6)tTen a_1 b…