当前位置: 首页 > news >正文

TypeScript 入门

课程地址

ts 开发环境搭建

npm i -g typescript

查看安装位置:

$ npm root -g
C:\Users\Daniel\AppData\Roaming\npm\node_modules

创建 hello.ts

console.log("hello, ts");

编译 ts 文件,得到 js 文件:

$ tsc foo.ts

类型声明

后置的类型声明

let a: number;a = 10;
a = 33;
// a = "hello";let b: string = "hello";
let c = true;   // Automatic type inferencefunction sum(a: number, b: number): number {return a + b;
}console.log(sum(1, 2));

类型

在这里插入图片描述

// 字面量类型
let a: 10;  // const a = 10;// 联合类型
let b: "male" | "female";
let c: boolean | string;
c = true;
c = "hello"// any 与 unknown
let d: any;
d = "hello";let e: unknown;
e = "hello";let s: string = d;
// s = e;   Type 'unknown' is not assignable to type 'string'
s = e as string;
s = <string>e;function f(): void {return;
}function f2(): never {  // 永远不会返回结果,终止进程throw new Error("error");
}

unknown 本质上是一个类型安全的 any

// 对象类型
let b: {name: string,age?: number,   // ? -> optional
};b = {name: "sunwukong"
};let c: {name: string,[propName: string]: any,
};// 函数类型
let d: (a: number, b: number) => number;d = function(a, b) {return a + b;
}// 数组类型
let e: string[];
e = ["a", "b", "c"];let g: Array<number>;
g = [1, 2, 3];// 元组
let h: [string, string];// enum
enum Gender {Male = 0,Female = 1,
}let p: {name: string, gender: Gender}p = {name: "sunwukong",gender: Gender.Male,
}// & 类型
let j: {name: string} & {age: number};// 类型别名
type t1 = 1 | 2 | 3 | 4 | 5;
let m: t1;

tsc 编译选项

自动编译文件

tsc foo.ts -w	# 文件改变时自动编译
tsc		# 根据 tsconfig.json 编译

tsconfig.json

{/*** 表示任意目录* 表示任意文件*/"include": ["./*"],"exclude": ["foo.ts"],// "files": ["./app.ts", "./index.ts"],"compilerOptions": {"target": "ES6",     // 指定 es 版本// "module": "ES6",// "lib": ["DOM"]"outDir": "./dist",// "outFile": "./dist/app.js",  // 将编译结果合并到 app.js"allowJs": false,"checkJs": false,   // 对 js 也做类型检查"removeComments": false,"noEmit": true,     // 不生成编译后的文件,只检查"noEmitOnError": true,   // 当有错误时不生成编译后的文件"strict": true,     // 打开下面的所有严格检查/*"alwaysStrict": true,   // -> use strict"noImplicitAny": true,"noImplicitThis": true,"strictNullChecks": true,*/},
}

使用 webpack 打包 ts 代码

npm init -y		# 初始化项目
npm i -D webpack webpack-cli typescript ts-loader

配置 webpack.config.js

const path = require("path");module.exports = {entry: "./src/index.ts",output: {path: path.resolve(__dirname + "/dist"),filename: "bundle.js",},module: {rules: [{test: /\.ts$/,use: "ts-loader",exclude: /node_modules/}]},mode: 'development',
}

配置 tsconfig.json

{"compilerOptions": {"module": "es6","target": "es6","strict": true,}
}

package.json 中增加 script 配置

  "scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack"},

最后 npm run build 即可

安装 3 个插件:

npm i -D html-webpack-plugin	# 生成 html 测试文件
npm i -D webpack-dev-server		# 编辑后自动重启服务
npm i -D clean-webpack-plugin	# 清除 dist 目录再构建
npm i -D @babel/core @babel/preset-env babel-loader core-js

package.json 中编写 webpack-server 的启动脚本:

  "scripts": {"start": "webpack serve --open"},

webpack.config.ts 中引入插件(使用 template.html 作为生成模板):

const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");module.exports = {entry: "./src/index.ts",output: {path: path.resolve(__dirname + "/dist"),filename: "bundle.js",},module: {rules: [{test: /\.ts$/,use: [{loader: "babel-loader",options: {presets: [["@babel/preset-env",{targets: {"chrome": "88"},"corejs": "3","useBuiltIns": "usage"  // 按需加载}]]}},"ts-loader"],exclude: /node_modules/}]},mode: 'development',plugins: [new HTMLWebpackPlugin({// title: "mytitle"template: "./src/template.html"}),new CleanWebpackPlugin(),],resolve: {  // 设置引用模块extensions: [".ts", ".js"]}
}

OOP

class

class Person {name: string = "sunwukong";static age: number = 18;readonly gender: string = "M";sayHello() {console.log("hello");}
}let p = new Person();console.log(p);
console.log(Person.age);
p.sayHello();

构造函数和 this

class Dog {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}bark() {console.log(`${this.name}: wangwang`);}
}let d = new Dog("wangcai", 4);console.log(d);
d.bark();

继承

class Animal {name: string;age: number;constructor(name: string, age: number) {this.name = name;this.age = age;}sayHello() {console.log("sayHello()");}
}class Dog extends Animal{run(){console.log(`${this.name} is running`);}sayHello(): void {  // 子类重写父类方法console.log("wangwangwang");}
}class Cat extends Animal{sayHello(): void {  // 子类重写父类方法console.log("miaomiaomiao");}
}const d1 = new Dog("wangcai", 5);
console.log(d1);
d1.sayHello();const c1 = new Cat("mimi", 3);
c1.sayHello();

super

super 表示父类

class Animal {name: string;constructor(name: string) {this.name = name;}sayHello() {console.log("sayHello()");}
}class Dog extends Animal {age: number;constructor(name: string, age: number) {super(name);this.age = age;}sayHello(): void {console.log("wangwangwang");}
}const d1 = new Dog("wangcai", 3);
console.log(d1);    // Dog { name: 'wangcai', age: 3 }
d1.sayHello();      // wangwangwang

抽象类

使用 abstract 修饰的类,不能用于实例化对象,只能被继承

抽象类中可以添加抽象方法,抽象方法必须被子类重写

abstract class Animal {name: string;constructor(name: string) {this.name = name;}abstract sayHello(): void;  // 必须被子类重写
}class Dog extends Animal {sayHello(): void {console.log("wangwangwang");}
}const d1 = new Dog("wangcai");
console.log(d1);    // Dog { name: 'wangcai', age: 3 }
d1.sayHello();      // wangwangwang

接口

用来定义一个类的结构(一个类应该包含哪些属性和方法,做类型限制)

接口中的所有属性都不能带有实际的值,接口只定义对象的结构(全是抽象方法),而不考虑实际值

interface Person{name: string;age: number;
}// 接口可以分离定义
interface Person {gender: string;sayHello(): void;
}class Male implements Person {name: string;age: number;gender: string;constructor(name: string, age: number, gender: string) {this.name = name;this.age = age;this.gender = gender;}sayHello(): void {console.log("hello");}
}

属性访问控制

class Person {private _name: string;private _age: number;constructor(name: string, age: number) {this._name = name;this._age = age;}get name() {        // per.namereturn this._name;}set name(name: string) {this._name = name;}get age() {return this._age;}set age(age: number) {if (age >= 0) {this._age = age;}}
}const p1 = new Person("sunwukong", 18);
console.log(p1);p1.name = "zhubajie";
console.log(p1);
console.log(p1.age);class C {// 直接将属性和访问控制定义在构造函数中constructor(public name: string, public age: number) {}
}

泛型

function fn<T> (a: T): T {return a;
}fn(10);
fn<string>("hello");function bar<T, K>(a: T, b: K): T {console.log(b);return a;
}bar<number, string>(10, "hello");interface Inter {length: number;
}
// 使用接口约束泛型的类型参数
function foo<T extends Inter>(a: T): number {return a.length;
}foo("123");     // string 有 length
foo({length: 10});// 类的泛型
class C<T> {name: T;constructor(name: T) {this.name = name;}
}const c = new C<string>("sunwukong");

贪吃蛇练习

// package.json
{"name": "snake","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack","start": "webpack serve --open"},"keywords": [],"author": "","license": "ISC","devDependencies": {"@babel/core": "^7.23.9","@babel/preset-env": "^7.23.9","babel-loader": "^9.1.3","clean-webpack-plugin": "^4.0.0","core-js": "^3.35.1","css-loader": "^6.10.0","html-webpack-plugin": "^5.6.0","less": "^4.2.0","less-loader": "^12.2.0","style-loader": "^3.3.4","ts-loader": "^9.5.1","typescript": "^5.3.3","webpack": "^5.89.0","webpack-cli": "^5.1.4","webpack-dev-server": "^4.15.1"}
}
// tsconfig.json
{"compilerOptions": {"module": "es6","target": "es6","strict": true,"noEmitOnError": true}
}
// webpack.config.ts
const path = require("path");
const HTMLWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");module.exports = {entry: "./src/index.ts",output: {path: path.resolve(__dirname + "/dist"),filename: "bundle.js",},module: {rules: [{test: /\.ts$/,use: [{loader: "babel-loader",options: {presets: [["@babel/preset-env",{targets: {"chrome": "88"},"corejs": "3","useBuiltIns": "usage"  // 按需加载}]]}},"ts-loader"],exclude: /node_modules/},{test: /\.less$/,use: ["style-loader","css-loader","less-loader"]}]},mode: 'development',plugins: [new HTMLWebpackPlugin({// title: "mytitle"template: "./src/template.html"}),new CleanWebpackPlugin(),],resolve: {  // 设置引用模块extensions: [".ts", ".js"]}
}
// index.ts
import "./style/index.less"
import Food from "./modules/food"
import ScorePanel from "./modules/score_panel"
import GameControl from "./modules/game_control";const f = new Food();
f.change();const gc = new GameControl();
// snake.ts
class Snake {head: HTMLElement;bodies: HTMLCollection;element: HTMLElement;constructor() {this.head = document.querySelector("#snake > div")!;this.bodies = document.getElementById("snake")!.getElementsByTagName("div");this.element = document.getElementById("snake")!;}get X() {return this.head.offsetLeft;}get Y() {return this.head.offsetTop;}set X(x: number) {if (this.X === x) return;if (x < 0 || x > 290) {throw new Error("snake_dead");}if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === x) {if (x > this.X) {x = this.X - 10;} else {x = this.X + 10;}}this.moveBody();this.head.style.left = x + "px";this.checkHeadBody();}set Y(y: number) {if (this.Y === y) return;if (y < 0 || y > 290) {throw new Error("snake_dead");}if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === y) {if (y > this.Y) {y = this.Y - 10;} else {y = this.Y + 10;}}this.moveBody();this.head.style.top = y + "px";this.checkHeadBody();}addBody() {this.element.insertAdjacentHTML("beforeend", "<div></div>");}moveBody() {for (let i = this.bodies.length - 1; i > 0; i--) {let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;(this.bodies[i] as HTMLElement).style.left = X + "px";(this.bodies[i] as HTMLElement).style.top = Y + "px";}}checkHeadBody() {for (let i = 1; i < this.bodies.length; i++) {let bd = this.bodies[i] as HTMLElement;if (this.X === bd.offsetLeft && this.Y === bd.offsetTop) {throw new Error("snake_dead");}}}
}
export default Snake;
// score_panel.ts
class ScorePanel {score = 0;level = 1;scoreEle: HTMLElement;levelEle: HTMLElement;maxLevel: number;upScore: number;constructor(maxLevel: number = 10, upScore: number = 10) {this.scoreEle = document.getElementById("score")!;this.levelEle = document.getElementById("level")!;this.maxLevel = maxLevel;this.upScore = upScore;}addScore() {this.scoreEle.innerHTML = ++this.score + "";if (this.score % this.upScore === 0) {this.levelUp();}}levelUp() {if (this.level < this.maxLevel) {this.levelEle.innerHTML = ++this.level + "";}}
}
export default ScorePanel;
// game_control.ts
import Snake from "./snake";
import Food from "./food";
import ScorePanel from "./score_panel";class GameControl {snake: Snake;food: Food;scorePanel: ScorePanel;direction: string = "";isLive = true;constructor() {this.snake = new Snake();this.food = new Food();this.scorePanel = new ScorePanel();this.init();}keydownHandler = (event: KeyboardEvent) => {this.direction = event.key;}init() {document.addEventListener("keydown", this.keydownHandler);this.run();}run() {let X = this.snake.X;let Y = this.snake.Y;switch(this.direction) {case "ArrowUp":Y -= 10;break;case "ArrowDown":Y += 10;break;case "ArrowLeft":X -= 10;break;case "ArrowRight":X += 10;break;}this.checkEat(X, Y);try {this.snake.X = X;this.snake.Y = Y;} catch (e) {alert((e as Error).message);this.isLive = false;}this.isLive && setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30);}checkEat(x: number, y: number) {if (x === this.food.X && y === this.food.Y) {console.log("ate food");this.food.change();this.scorePanel.addScore();this.snake.addBody();}}}export default GameControl;
// food.ts
class Food {element: HTMLElement;constructor() {// `!` 表示判定该语句的结果不可能为空this.element = document.getElementById("food")!;}get X() {return this.element.offsetLeft;}get Y() {return this.element.offsetTop;}change() {let left = Math.round(Math.random() * 29)* 10;let top = Math.round(Math.random() * 29)* 10;this.element.style.left = top + "px";this.element.style.top = left + "px";}
}
export default Food;
// index.less
* {margin: 0;padding: 0;box-sizing: border-box;
}body {font: bold 20px Courier;
}#main {width: 360px;height: 420px;background-color: #b7d4a8;margin: 100px auto;border: 10px solid black;border-radius: 10px;display: flex;flex-flow: column;align-items: center;justify-content: space-around;#stage {width: 304px;height: 304px;border: 2px solid black;position: relative;#snake {&>div {width: 10px;height: 10px;background-color: black;border: 1px solid #b7d4a8;position: absolute;}}#food {width: 10px;height: 10px;position: absolute;left: 40px;top: 100px;display: flex;flex-flow: row wrap;justify-content: space-between;align-content: space-between;&>div {width: 4px;height: 4px;background-color: black;}}}#score-panel {width: 300px;display: flex;justify-content: space-between;}}

相关文章:

TypeScript 入门

课程地址 ts 开发环境搭建 npm i -g typescript查看安装位置&#xff1a; $ npm root -g C:\Users\Daniel\AppData\Roaming\npm\node_modules创建 hello.ts&#xff1a; console.log("hello, ts");编译 ts 文件&#xff0c;得到 js 文件&#xff1a; $ tsc foo.…...

linux 磁盘相关操作

1.U盘接入虚拟机 &#xff08;1&#xff09;在插入u盘时&#xff0c;虚拟机会检测usb设备&#xff0c;在弹出窗口选择连接到虚拟机即可。 &#xff08;2&#xff09;或 直接在虚拟机--->可移动设备--->找到U盘---->连接 2.检测U盘是否被虚拟机识别 ls /dev/sd* 查…...

PyTorch: torch.max()函数详解

torch.max函数详解&#xff1a;基于PyTorch的深入探索 &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;torch.max()函数简介&#x1f333;&#x1f333;torch.max()的返回值&#x1f333;&#x1f333;torch.max()的应用示例&#x1f333;&am…...

Rust基础拾遗--核心功能

Rust基础拾遗 前言1.所有权与移动1.1 所有权 2.引用3.特型与泛型简介3.1 使用特型3.2 特型对象3.3 泛型函数与类型参数 4.实用工具特型5.闭包 前言 通过Rust程序设计-第二版笔记的形式对Rust相关重点知识进行汇总&#xff0c;读者通读此系列文章就可以轻松的把该语言基础捡起来…...

MySQL:常用指令

MySQL官网 一、在Windows 系统 cmd窗口里执行的命令 启动:net start MySQL停止:net stop MySQL卸载:sc delete MySQL 二、在macOS系统终端里执行的命令 启动&#xff1a;mysql.server start停止&#xff1a;mysql.server stop重启&#xff1a;mysql.server restart 三、执行帮…...

Scrapy:Python中强大的网络爬虫框架

Scrapy&#xff1a;Python中强大的网络爬虫框架 在当今信息爆炸的时代&#xff0c;从互联网上获取数据已经成为许多应用程序的核心需求。Scrapy是一款基于Python的强大网络爬虫框架&#xff0c;它提供了一种灵活且高效的方式来提取、处理和存储互联网上的数据。本文将介绍Scrap…...

linux系统非关系型数据库redis的配置文件

redis配置文件 Redis的配置文件位于Redis安装目录下&#xff0c;文件名为redis.conf&#xff0c;配置项说明如下 Redis默认不是以守护进程的方式运行&#xff0c;可以通过该配置项修改&#xff0c;使用yes启用守护进程 daemonize no当Redis以守护进程方式运行时&#xff0c;Red…...

电力负荷预测 | 基于LSTM、TCN的电力负荷预测(Python)

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 电力负荷预测 | 基于LSTM、TCN的电力负荷预测(Python) 源码设计 #------------------...

Java+SpringBoot实习管理系统探秘

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…...

c入门第十六篇——学生成绩管理系统

师弟&#xff1a;“师兄&#xff0c;我最近构建了一个学生成绩管理系统&#xff0c;有空试用一下么&#xff1f;” 我&#xff1a;“好啊&#xff01;” 一个简单的学生成绩管理系统&#xff0c;基本功能包括&#xff1a;添加学生信息、显示所有学生信息、按学号查找学生信息、…...

大文件上传如何做断点续传?

文章目录 一、是什么分片上传断点续传 二、实现思路三、使用场景小结 参考文献 一、是什么 不管怎样简单的需求&#xff0c;在量级达到一定层次时&#xff0c;都会变得异常复杂 文件上传简单&#xff0c;文件变大就复杂 上传大文件时&#xff0c;以下几个变量会影响我们的用…...

SpringCloud-Eureka原理分析

Eureka是Netflix开源的一款用于实现服务注册与发现的工具。在微服务架构中&#xff0c;服务的动态注册和发现是必不可少的组成部分&#xff0c;而Eureka正是为了解决这一问题而诞生的。 一、为何需要Eureka 在微服务架构中&#xff0c;服务之间的协同合作和高效通信是至关重要…...

LeetCode周赛——384

1.修改矩阵&#xff08;模拟&#xff09; class Solution { public:vector<vector<int>> modifiedMatrix(vector<vector<int>>& matrix) {int n matrix.size();int m matrix[0].size();vector<int> ans(m);for(int i 0; i < m; i)for(…...

C#,巴都万数列(Padonve Number)的算法与源代码

1 巴都万数列&#xff08;Padovan Sequence&#xff09; 巴都万数列&#xff08;Padovan Sequence&#xff09;是一个整数数列。 首数个值为1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21, 28, 37 ... 此数列以建筑师理察巴都万命名&#xff0c;他的论文Dom&#xff08;1994年&a…...

NSSCTF Round#18 RE GenshinWishSimulator WP

恶搞原神抽卡模拟器 看到软件的界面&#xff0c;大致有三种思路&#xff1a; 修改石头数量一直抽&#xff0c;如果概率正常肯定能抽到&#xff08;但是估计设置的概率是0&#xff09;在源码里找flag的数据把抽卡概率改成100%直接抽出来 Unity逆向&#xff0c;根据经验应该dnsp…...

鸿蒙系统对应安卓版本

鸿蒙系统对应安卓版本 使用安卓studio 新建一个app 然后添加代码打印&#xff1a; Log.d(“MainActivity”, "SDK Version: " Build.VERSION.SDK_INT); 或者把 Build.VERSION.SDK_INT 添加到显示的字符串上面 我这里 build.gradle.kts 配置 android {compileSdk…...

算法-16-并查集

并查集简介 并查集&#xff1a;一开始&#xff0c;把a&#xff0c;b&#xff0c;c放入并查集&#xff0c;a自己一个集合&#xff0c;b自己一个&#xff0c;c自己一个 提供的方法 1.boolean isSameSet(a,b)&#xff0c;判断ab是否在同一个集合 2.void union(a,b),把a所…...

【C/C++】2024春晚刘谦春晚魔术步骤模拟+暴力破解

在这个特别的除夕夜&#xff0c;我们不仅享受了与家人的温馨团聚&#xff0c;还被电视机前的春节联欢晚会深深吸引。特别是&#xff0c;魔术师刘谦的精彩表演&#xff0c;为我们带来了一场视觉和心灵的盛宴。在我的博客“【C/C】2024春晚刘谦春晚魔术步骤模拟暴力破解”中&…...

Java运算符和表达式

Java运算符和表达式 和C语言一样&#xff0c;java也有基础的运算符和表达式&#xff0c;用来完成一些基础的数学计算&#xff0c;以及逻辑运算&#xff0c;我们一起来学习一下吧。 算数运算符 首先&#xff0c;这个算数运算符与数学中即C语言的运算符的功能一样&#xff0c;利…...

波奇学Linux:软硬链接

ln指令建立链接 软链接 硬链接 所属者的前的数字表示硬链接数&#xff0c;引用计数&#xff0c;file.txt和soft_link是软链接所以都为2 软链接有独立inode&#xff0c;硬链接没有&#xff0c;所以硬链接不是独立文件&#xff0c;软链接是独立文件&#xff0c;且硬链接的属性会…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

云计算——弹性云计算器(ECS)

弹性云服务器&#xff1a;ECS 概述 云计算重构了ICT系统&#xff0c;云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台&#xff0c;包含如下主要概念。 ECS&#xff08;Elastic Cloud Server&#xff09;&#xff1a;即弹性云服务器&#xff0c;是云计算…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...