禹神TypeScript课程记录

TypeScript与JavaScript的关系

  1. TypeScript是一个基于JavaScript的扩展语言
  2. TypeScript包含了JavaScript的所有内容
  3. TypeScript增加了:静态类型检查、接口、泛型等很多现代开发特性,更适合大型项目。
  4. TypeScript需要编译为JavaScript,然后才能在浏览器或其他环境运行。
为什么需要TypeScript
  1. JavaScript 当年诞生时的定位是浏览器脚本语言,用于在网页中嵌入简单的逻辑,且代码量很少。
  2. 随着时间的推移,JavaScript 变得越来越流行,如今的 JavaScript 已经可以全栈编程
  3. 现如今的 JavaScript 应用场景比当年丰富的多,代码量也比当年大很多,随便一个JavaScript 项目的代码量,可以轻松的达到几万行,甚至十几万行!
  4. 然而 JavaScript 当年“出生简陋”,没考虑到如今的应用场景和代码量,逐渐就出现了很多困扰
JavaScript中的困扰
  1. 不清不楚的数据类型
  2. 有逻辑的漏洞
  3. 访问不存在的属性
  4. 低级的拼写错误
静态类型检查
  • 在代码运行前进行检查,发现代码的错误或不合理之处,减小运行时出现异常的几率,此种检查叫『静态类型检查』,TypeScript 和核心就是『静态类型检查』,简言之就是把运行时的错误前置。
  • 同样的功能,TypeScript 的代码量要大于 JavaScript,但由于 TypeScript 的代码结构更加清晰,在后期代码的维护中 TypeScript 却胜于 JavaScript。
编译TypeScript

浏览器不能直接运行TypeScript代码,需要编译为JavaScript再交由浏览器解析器执行。

命令行编译
  1. 创建demo.ts文件
const person = {name: '张三',age: 10
}
console.log(`我叫${person.name}, 今年:${person.age}岁`);
  1. 安装TypeScript
npm i typescript -g
  1. 编译TypeScript
tsc demo.ts
自动化编译
  1. 创建TypeScript编译控制文件
tsc --init
  1. 监视目录中的 .ts 文件变化
tsc --watch 或 tsc --w
  1. 编译出错时,不生成js文件

在tsconfig.json文件中,放开配置的注释即可。

"noEmitOnError": true或在启动时添加
tsc --noEmitOnError --watch
类型声明

声明格式

let 变量:类型
变量-设置类型
let a:string //只能存字符串类型
let b:number //只能存数字类型
let c:boolean //只能存布尔类型a = "hello";
//a = 100 不能把100赋值给a
b = 10;
c = true

注意:类型必须声明后才能使用,否则会报错。

方法-设置类型
// 设置参数类型和返回值类型
function sum(a: number, b: number):number{return a + b;
}
sum(1,2);//调用sum时,必须传入数字类型

字面量类型

let x:'hello';
x = 'hello';

x只能为'hello'。

类型推断

TypeScript会根据我们的代码进行类型推导。

let d = 'abc';
d = 9;//类型不同,赋值会报错

变量d的类型为字符串,不能赋值数字

注意:类型推断面对复杂类型时容易出问题,所以还是要明确的编写类型声明。

类型总览
JavaScript数据类型
  1. string
  2. number
  3. boolean
  4. null
  5. undefined
  6. bigint
  7. symbol
  8. object

object类型又包括:Array,Function,Date等。。。

TypeScript数据类型
  1. 包含JavaScript的数据类型
  2. 新增6个类型
    1. any
    2. unkown
    3. never
    4. void
    5. tuple
    6. enum
  1. 两个自定义类型的方式
    1. type
    2. interface
包装类型

在JavaScript中的这些内置构造函数:String, Number, Boolean用于创建对应的包装类型,在日常开发中很少使用。因此在TypeScript中进行类型声明,通常使用的是小写的:string, number,boolean这种原生数据类型。

let test:string
test = "abc"
// test = new String();let test1:String
test1 = "def"
test1 = new String();console.log(typeof test); //输出:string
console.log(typeof test1); //输出:object
原始类型 VS 包装类型
  1. 原始类型:如 number、string、boolean ,在 JavaScript 中是简单数据类型,它们在内存中占用空间少,处理速度快。
  2. 包装对象:如 Number 对象、String 对象、 Boolean 对象,是复杂类型,在内存中占用更多空间,在日常开发时很少由开发人员自己创建包装对象。
  3. 自动装箱:JavaScript 在必要时会自动将原始类型包装成对象,以便调用方法或访问属性。

代码

let str = 'hello'
console.log(str.length);

内部执行逻辑:

常用类型与语法
any

any表示任意类型,一旦变量设置为any,那就意味着放弃了对该变量的类型检查。

//变量ab,可以赋予任何类型的值
let ab:any
ab = 'a'
ab = 9//变量bb,如果不声明类型,TypeScript推断出来的类型就是any(隐式的any)
let bb
bb = 'b'
bb = 10//any类型的变量可以赋值给任意类型的变量
let cb:string
cb = ab
nuknown

unknown是未知类型,适用于:起初不确定数据的具体类型,需要后期才确定。

  1. unknown可以理解为类型安全的any
let k:unknown
k = 1
k = true
k = "hello"//不能将unknown类型赋值给string类型
// let ka:string
// ka = k//unknown转换为指定类型
let ka:string
ka = 'str';
//方式1:类型判断
if(typeof k === 'string'){ka = k;console.log(ka);
}//方式2:断言
ka = k as string;
console.log(ka);//方式3:转换类型
ka = <string> k;
console.log(ka);

注意:要想使用unknown类型的变量,必须将其转换为具体类型。否则,读取变量的属性、方法会报错

never

never表示:任何值都不是,即:不能有值。例如:undefined,null,‘’都不行。

  1. never几乎不会用来直接限制变量
let n1:never

此时,n1不能再设置任何值

  1. never是TypeScript推断出来的
let n2: string
n2 = 'hello'
if (n2 === 'string') {console.log(n2.toUpperCase());
} else {console.log(n2);//这里推断出来的类型就是never
}
  1. 限制函数返回值
function throwError(str: string): never {throw new Error(str);
}
throwError("abc");//调用时就不用尝试获取其返回值了
void

void的含义是空,即函数不返回任何值,调用者也不应该依赖其返回值进行任何操作。

  1. void通常用于函数的返回值声明
function logMessage(msg: string): void {console.log(msg);
}
console.log("hello world");
  1. 无返回值也可以这样写
function logMessage1(msg: string): void {console.log(msg);return;
}function logMessage2(msg: string): void {console.log(msg);return undefined;
}
  1. 返回void与undefined的区别

返回void时,不能操作返回值

function returnVoid(msg: string): void {console.log(msg);
}
let voidResult = returnVoid("abc");
//尝试操作返回值,会报错
if (voidResult) {console.log(voidResult);
}

返回undefined时,可以操作返回值

function returnUndefined(msg: string): undefined {console.log(msg);return undefined;
}
let undefinedResult = returnUndefined("test");
if (undefinedResult) {console.log(undefinedResult);
}
理解 void 与 undefined
  • void 是一个广泛的概念,用来表达“空”,而:undefined:则是这种“空”的具体实现。
  • 因此可以说:undefined是 void 能接受的一种“空”的状态。也可以理解为: void 包含 undefined:,但 void 所表达的语义超越了 undefined ,void 是一种意图上的约定,而不仅仅是特定值的限制。
总结

如果一个函数返回类型为 void ,那么:

  1. 从语法上讲:函数是可以返回 undefined 的,至于显式返回,还是隐式返回,这无所谓!
  2. 从语义上讲:函数调用者不应关心函数返回的值,也不应依赖返回值进行任何操作!即使我们知道它返回了 undefined
object

实际开发中使用较少,因为范围太大。

object(小写)

所有非原始类型,可存储:对象,函数,数组等。

let o: object
o = {}
o = [1, 2, 3]
o = function () { }
o = new String("abc")
class Person { }
o = new Person();o = 1 //报错,这是原始类型

Object(大写)

除了 null 和 undefined 的任何值。

let O: Object
O = 1
O = true
O = "abc"O = null //报错,null不能赋值给Object
O = undefined //报错,undefined不能赋值给Object
声明对象类型
  1. 实际开发中,限制一般对象,通常使用以下形式。
let user: { name: string, age?: number }
let user1: { name: string; age?: number }
let user2: {name: string;age?: number
}//给类型赋值
user = { name: "zhangsan", age: 10 }
user1 = {name: "lisi"}
user2 = {name: "wangwu", age:"aab"} //会报错,age类型不是number
  1. 索引签名:允许定义对象具有任意数量的属性,这些属性的键与值是可变的。常用与:描述类型不确定的属性。
let user4: {name: string,age?: number,[key: string]: any
}
user4 = {name: "zs",age: 12,like: 'ball'
}
声明函数类型

方式1:TypeScript 中的 =>在函数类型声明时表示函数类型,描述其参数类型和返回类型

let sum1: (a: number, b: number) => number
sum1 = function (a, b) {return a + b
}

这种方式定义的函数不能提升(hoisted),不能在声明前被调用

方式2:

console.log(sum2(1, 2));
function sum2(a: number, b: number): number {return a + b
}

这种方式定义的函数可以在声明前被调用,函数会被提升(hoisted)

方式3:箭头函数声明时定义

let sum3 = (a: number, b: number): number => a + b;
console.log(sum3(1,2));
声明数组类型
let arr1: string[]
let arr2: Array<string>arr1 = ['1', '2']
arr2 = ['3', '4']
tuple-元组

元组(Tuple)是一种特殊的数组类型,可以存储固定数量的元素,并且每个元素的类型是已知的且可以不同。元组用于精确描述一组值的类型,?表示可选元素。

//第一个元素必须是string类型,第二个元素必须是number类型
let tp1: [string, number];
tp1 = ["a", 2];
//第一个元素必须是string类型,第二个元素可为空,如果存在,必须是boolean类型
let tp2: [string, boolean?];
tp2 = ['a', true]
//第一个元素必须是number类型,后面的元素可以是任意数量的string类型
let tp3: [number, ...string[]]
tp3 = [1, "a","b"]
enum-枚举

枚举 (enum)可以定义一组命名常量,它能增强代码的可读性,也让代码更好维护。

定义枚举

enum Direction {Up,Down,Left,Right
}
console.log(Direction);
console.log(Direction.Up);// 输出0
console.log(Direction[0]);// 输出Up

枚举中的元素的值是从0开始递增的。

enum Direction {Up,Down = 5,Left,Right
}

可以在初始化枚举时设置值,设置值后面的会递增,前面的不会(从0开始)

使用枚举的案例

未使用枚举

function direction(str: string) {if (str === 'up') {console.log("上");} else if (str === 'down') {console.log("下");} else if (str === 'left') {console.log("左");} else if (str === 'right') {console.log("右");}
}
console.log(direction1(up));

使用枚举

enum Direction {Up,Down,Left,Right
}function direction1(str: Direction) {if (str === Direction.Up) {console.log("上");} else if (str === Direction.Down) {console.log("下");} else if (str === Direction.Left) {console.log("左");} else if (str === Direction.Right) {console.log("右");}
}console.log(direction1(Direction.Left));
字符串枚举
enum Direction1 {Up = 'up',Down = 'down',Left = 'left',Right = 'right'
}
let d1:Direction1 = Direction1.Down;
console.log(d1);
常量枚举

官方描述:常量枚举是一种特殊枚举类型,它使用const 关键字定义,在编译时会被内联,避免生成一些额外的代码。

何为编译时内联?

所谓“内联”其实就是 TypeScript 在编译时,会将枚举成员引用替换为它们的实际值而不是生成额外的枚举对象。这可以减少生成的 JavaScript 代码量,并提高运行时性能。

const enum Direction2 {Up,Down,Left,Right
}
console.log(Direction2.Down);
type

type可以为任意类型创建别名,让代码变得简洁、可读性更强,同时能更方便的进行类型复用和扩展

基本用法

类型别名使用 type 关键字定义, type 后跟类型名称,例如下面代码中 num:是类型别名。

type num = number;
let count: num;
count = 1;
console.log(count);
联合类型

联合类型是一种高级类型,它表示一个值可以是几种不同类型之一。

type Status = number | string;
function printStatus(status: Status) {console.log(status);
}
printStatus('abc');
printStatus(123);

传入的参数可以是number也可以是string。

交叉类型

交叉类型(intersection Types)允许将多个类型合并为一个类型。合并后的类型将拥有所有被合并类型的成员。交叉类型通常用于对象类型。

type Area = {width: number;heigth: number;
}type Address = {cell: number;//单元号room: string;//房间号
}type House = Area & Address;
const house: House = {width: 1,heigth: 2,cell: 3,room: "001"
}
console.log(house);
特殊情况
//定义一个类型,这个类型是一个无返回值的函数。.
type Func = () => void;//TypeScript并不限制其返回
const myFunc: Func = () => {console.log("abc");return "abc";
}
myFunc();//Func类型作为参数使用
function testMyFuncParam(f: Func) {f();
}
testMyFuncParam(() => {console.log("testMyFunc");
});//Func类型作为返回值使用
function testMyFuncReturn(): Func {return () => {console.log("no return");}
}
testMyFuncReturn()();
定义类
class User {//声明属性name: stringage: numberconstructor(name: string, age: number) {this.name = name;this.age = age;}sayHi() {console.log(`你好,我是:${this.name},年龄:${this.age}`);}
}
let us = new User("小明", 10);
us.sayHi();

构造函数简写

constructor(public name: string,public age: number) {}
类的继承
class Vip extends User {grade: number;constructor(name: string, age: number, grade: number) {super(name, age);this.grade = grade;}override sayHi(): void {console.log(`我是:${this.name} 年龄:${this.age} 年级:${this.grade}`);}study() {console.log(`${this.name}努力学习中。。。`);}
}
属性修饰符

public

属性默认是被public修饰。

class User {//声明属性public name: stringage: numberconstructor(name: string, age: number) {this.name = name;this.age = age;}sayHi() {console.log(`你好,我是:${this.name},年龄:${this.age}`);}
}
let us = new User("小明", 10);
console.log(us.name);
protected

父类定义方法

protected getName() {console.log(`我是:${this.name}`);
}

子类使用

getParentName() {super.getName();
}
private

父类创建私有属性:id

constructor(public name: string,public age: number,private id: number) {
}

并提供私有方法

private getId() {return this.id;
}

然后再提供一个public方法

getIdInfo() {console.log('我的id是:' + this.getId());
}

最后使用

let us = new User("张三", 30, 1001);
us.getIdInfo();

注意:不能直接使用new出来的对象调用私有方法。

readonly
class Car {constructor(public readonly vin: string,//车辆识别码public readonly year: number,//出厂年份public color: string) {}displayInfo() {console.log(`识别码:${this.vin}出厂年份:${this.year}颜色:${this.color}`);}
}let car = new Car('JW2222FJI04832', 2024, 'red');
car.displayInfo();
car.vin = '123'//只读属性不能修改
抽象类

概述:类是一种无法被实例化的类,专门用来定义类的结构和行为,类中可以写抽象方法,也可以写具体实现。抽象类主要用来为其派生类提供一个基础结构,要求其派生类必须实现其中的抽象方法。

简记:抽象类不能实例化,其意义是可以被继承,抽象类里可以有普通方法、也可以有抽象方法。

//抽象包裹类
abstract class Package {constructor(public weight: number) {}abstract calculate(): number;printPackage() {console.log(`包裹重量:${this.weight} 费用:${this.calculate()} 元`);}
}//标准包裹类
class StdPackage extends Package {constructor(weight: number) {super(weight)}calculate(): number {return 1;}
}
let std = new StdPackage(2);
std.printPackage();

总结:何时使用抽象类?

  1. 定义通用接口:为一组相关的类定义通用的行为(方法或属性)时。
  2. 提供基础实现:在抽象类中提供某些方法或为其提供基础实现,这样派生类就可以继承这些实现。
  3. 确保关键实现 : 强制派生类实现一些关键行为。
  4. 共享代码和逻辑:当多个类需要共享部分代码时,抽象类可以避免代码重复。
接口

interface 是一种定义结构的方式,主要作用是为:类、对象、函数等规定一种契约,这样可以确保代码的一致性和类型安全,但要注意 interface 只能定义格式,不能包含任何实势

定义类结构
interface UserInterface {name: stringage: numbersayHi(n: number): void
}class MyUser implements UserInterface {constructor(public name: string,public age: number) { }sayHi(n: number): void {console.log(`你好,我是${this.name} 年龄是:${this.age} 我想说:${n}`);}
}
let myUser = new MyUser("李四", 20);
myUser.sayHi(666);
定义对象结构
interface UserInterface1 {name: stringreadonly gender: stringage?: numberrun: (n: number) => void
}
const myUser1: UserInterface1 = {name: "王五",gender: "男",age: 17,run(n) {console.log(`你好,我是${this.name}, 性别:${this.gender}, 年龄:${this.age}, 我想说:${n}`);}
}
myUser1.run(888);
定义方法结构
interface MyFunction {(a: number, b: number): number;
}const sumResult: MyFunction = (a, b) => a + b;
console.log(sumResult(1, 2));
接口之间的继承
interface ParentInterface {name: stringage: number
}
interface ChildInterface extends ParentInterface {grade: number
}
const john: ChildInterface = {name: "john",age: 30,grade: 10
}
console.log(`姓名:${john.name}年龄:${john.age}分数:${john.grade}`
);
接口合并
interface PersonInterface {name: stringage: number
}
interface PersonInterface {//声明方法run(n: number): void//把方法复制给变量run1: (n: number) => void
}
class person1 implements PersonInterface {// name:string// age:number// constructor(name:string, age:number){//     this.name =name;//     this.age = age;// }constructor(public name: string, public age: number) { }run(n: number): void {console.log(`run 方法,参数:${n}`);}// run1: (n: number) => void = (n: number) => {// }run1 = (n: number) => {console.log(`run1 方法,参数:${n}`);}
}

总结:何时使用接口?

  1. 定义对象的格式:描述数据模型、AP! 响应格式、配置对象!.…等等,是开发中用的最多的场景。
  2. 类的契约:规定一个类需要实现哪些属性和方法。
  3. 扩展已有接口:一般用于扩展第三方库的类型, 这种特性在大型项目中可能会用到
一些相似的概念
interface与type的区别

相同点: interface 和 type 都可以用于定义对象结构,在定义对象结构时两者可以互换。

不同点:

  1. interface:更专注于定义对象和类的结构,支持继承、合并
  2. type:可以定义类型别名、联合类型、交叉类型,但不支持继承和自动合并。
定义对象结构
interface Obj1 {name: stringage: numberrun(s: string): void
}
//使用
let obj1: Obj1 = {name: "zhangsan",age: 10,run(s: string): void {console.log(`this is run method, param: ${s}`);}
}type Obj2 = {name: stringage: numberrun: (s: string) => void
}
//使用
const obj2: Obj2 = {name: "lisi",age: 10,run: (s: string): void => {console.log(`这是lisi, 编号:${s}`);}
}
交叉
//类型交叉
type Cross1 = {name: stringage: number
} & {run: (s: string) => void
}
type Cross2 = Cross1 & {sayHi(): void
}
const student: Cross2 = {name: "stu",age: 10,run(s) {console.log("this is run method!", s);},sayHi() {console.log("say hi");}
}
console.log(student.name, student.age);
student.run("abc");
student.sayHi();//接口交叉
interface Cross3 {name: stringage: numberrun: (s: string) => void
}
interface Cross3 {sayHi(): void
}
interface Cross4 extends Cross3 {grade: number
}
const stu1: Cross4 = {name: "stu123",age: 10,grade: 30,run(s) {console.log(`this is run method ,param:${s}`);},sayHi() {console.log("this is say hi method!");},
}
console.log(stu1.age, stu1.name, stu1.grade);
stu1.sayHi();
stu1.run("abc");
interface与抽象类的区别

相同点:

都能定义一个类的格式(定义类应遵循的契约)

不相同:

  1. 接口:只能描述结构,不能有任何实现代码,一个类可以实现多个接口。
  2. 抽象类:既可以包含抽象方法,也可以包含具体方法,一个类只能继承一个抽象类

一个类可以实现多个接口

interface FlyInterface {fly(): void
}
interface SwimInterface {swim(): void
}
class Duck implements FlyInterface, SwimInterface {fly(): void {console.log("the duck can fly!");}swim(): void {console.log("the duck can swim!");}
}
泛型

泛型允许我们在定义函数、类或接口时,使用类型参数来表示未指定的类型,这些参数在具体使用时,才被指定具体的类型,泛型能让同一段代码适用于多种类型,同时仍然保持类型的安全性。

泛型函数
function getData1<T, U>(data1: T, data2: U): T {console.log(`data1:${data1}`);console.log(`data2:${data2}`);return data1;
}
getData1<string, string>("abc", 'def');
泛型接口
interface Fx<T> {name: stringage: numberother: T
}
let f1: Fx<string>;
let f2: Fx<number>;
f1 = {name: "zs",age: 10,other: "abc"
}f2 = {name: "ls",age: 20,other: 123
}
泛型约束
interface LengthInterface {length: number
}
//传入的值必须要有length属性
function getLength<T extends LengthInterface>(data: T): void {console.log(data.length);
}
// getLength<number>(100);
getLength<string>('123');
getLength<Array<string>>(["1","2"]);
泛型类
class Queue<T> {constructor(public name: string,public age: number,public data: T) { }run() {console.log(this.name, this.age);console.log(this.data);}
}
let queue = new Queue<number>('zs', 10, 100);
queue.run();
类型声明文件

类型声明文件是 TypeScript 中的一种特殊文件,通常以.d.ts 作为扩展名。它的主要作用是为现有的 JavaScript 代码提供类型信息,使得 TypeScript 能够在使用这些 JavaScript 库或模块时进行类型检查和提示。

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

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

相关文章

【优选算法篇】编织算法的流动诗篇:滑动窗口的轻盈之美

文章目录 C 滑动窗口详解&#xff1a;基础题解与思维分析前言第一章&#xff1a;热身练习1.1 长度最小的子数组解法一&#xff08;暴力求解&#xff09;解法二&#xff08;滑动窗口&#xff09;滑动窗口的核心思想图解分析滑动窗口的有效性时间复杂度分析易错点提示 1.2 无重复…

vue3基础入门以及常用api使用

setup setup 的返回值可以是函数 data(){ return { a:111, c:this.name } }, setup(){ let name 1111 return ()> 哈哈哈 }//结果页面就是会显示 哈哈哈setup和 OptionsAPI关系 data能和setup能同时存在&#xff0c;但不建议 data能读到setup里边的数据 setup是最早的生命…

Java基础06-常用API

六、常用API API &#xff1a;应用程序编程接口 1、Object 作用&#xff1a;Object类是Java中所有类的祖宗类&#xff0c;因此&#xff0c;Java中所有类的对象都可以直接使用0bject类中提供的一些方法。 方法名说明toString()返回字符串数据equals(Object o)比较两个对象地址是…

使用 Docker-compose 部署达梦 DM 数据库

目录 1. 获取达梦 DM8 Docker 镜像并上传到 Harbor 服务器 2. Docker-compose 部署达梦 DM8 数据库 3. 配置 dm.ini 文件 4.完整的 dm.ini 文件 最近&#xff0c;将 MySQL 数据库迁移到了达梦 DM8 数据库。本文将分享如何通过 Docker-compose 部署达梦 DM8 数据库的过程&am…

ARM(5)内存管理单元MMU

一、虚拟地址和物理地址 首先&#xff0c;计算机系统的内存被组成一个由M个连续的字节大小组成的数组。每字节都会有一个唯一的物理地址。CPU访问内存最简单的方式就是使用物理地址。如下图&#xff1a; 图 1 物理地址,物理寻址 而现在都是采用的都是虚拟寻址的方法。CPU生成一…

gitlab保护分支设置

版本&#xff1a;gitlab10.2.2 一旦设置master分支被保护&#xff0c;除了管理员之外的任何用户都无法直接向master提交代码&#xff0c;只要提交代码就会报错 # git push -u origin master Total 0 (delta 0), reused 0 (delta 0) remote: GitLab: You are not allowed to pu…

在CentOS系统下实现准实时SFTP上传指定目录下前2分钟的文件

在CentOS系统下实现准实时SFTP上传指定目录下前2分钟的文件 引言准备工作编写Shell脚本执行脚本定时执行脚本注意事项结论引言 在企业级的文件同步和备份场景中,经常需要将本地目录中最新生成的文件(如前2分钟内生成的文件)快速上传到远程服务器的指定目录。为了实现这一目…

unity 屏幕波动反馈打击效果(附资源下载)

unity 屏幕波动反馈打击效果 一枪打出去整个屏幕都回波动的效果反馈。 知识点&#xff1a; 1、动画事件 2、屏幕后处理 效果如图&#xff1a;&#xff08;波动速度浮动都可调整&#xff09; 附件下载

【互联网业务风控】

1. 不同场景下的业务风控 1.1 账户业务风控 1.1.1账户安全 • 账号安全是所有强账号体系应用的基础&#xff0c; 强账号体系&#xff0c;如电商、网游、第三方支付、社交网络、即时通讯等&#xff1b;是需要登录后产生数据和交互的应用&#xff0c; 弱账号体, 如搜索、导航、…

关键词提取技术:TF-IDF 和 TextRank 简介

关键词提取是自然语言处理中的重要任务之一&#xff0c;用于自动提取文档中最能代表其内容的词汇。两种常用的关键词提取技术是 TF-IDF 和 TextRank。它们的工作机制和应用场景有所不同&#xff0c;下面将详细解释这两种技术。 1. TF-IDF&#xff08;Term Frequency - Inverse…

Python | Leetcode Python题解之第485题最大连续1的个数

题目&#xff1a; 题解&#xff1a; class Solution:def findMaxConsecutiveOnes(self, nums: List[int]) -> int:maxCount count 0for i, num in enumerate(nums):if num 1:count 1else:maxCount max(maxCount, count)count 0maxCount max(maxCount, count)return …

未来智慧建筑:人工智能技术的无限可能

随着科技的不断发展&#xff0c;人工智能技术正逐渐渗透到各行各业&#xff0c;其中&#xff0c;在智能建筑领域的应用备受瞩目。智能建筑结合了传统建筑与先进科技的完美融合&#xff0c;在提高建筑效率、节能环保、增强安全性等方面发挥着重要作用。本文将探讨人工智能技术在…

MyBatis的占位符(day36)

1 学习目标 重点掌握#{}占位符的使用 2 MyBatis的占位符介绍 #{}占位符: 相当于JDBC中的问号(?)占位符&#xff0c;是为SQL语句中的值进行占位&#xff0c;如果参数值是字符串或者日期类型&#xff0c;会进行转义处理 我们使用#{}写的SQL语句: <update id"delete…

蓝牙资讯|苹果AirPods Pro 2耳机推送开发者Beta固件

科技媒体 MacRumors 报道&#xff0c;苹果公司邀请开发者&#xff0c;针对 Lightning 和 USB-C 接口的 AirPods Pro 2 耳机&#xff0c;推送了新的 7B5013d 固件版本&#xff0c;较之前的 7B5013c 有所提升。 苹果未来会向所有 AirPods Pro 2 用户推送本次固件更新&#xff0…

react18中实现简易增删改查useReducer搭配useContext的高级用法

useReducer和useContext前面有单独介绍过&#xff0c;上手不难&#xff0c;现在我们把这两个api结合起来使用&#xff0c;该怎么用&#xff1f;还是结合之前的简易增删改查的demo&#xff0c;熟悉vue的应该可以看出&#xff0c;useReducer类似于vuex&#xff0c;useContext类似…

springboot项目通过maven的profile功能实现通过不同文件夹的方式来组织不同环境配置文件

写在前面 本文看下springboot项目如何通过文件夹的方式来组织不同环境配置文件。 1&#xff1a;正文 一般的我们写springboot项目时配置文件是这个样子的&#xff1a; appliction.yaml --> 通过spring.profiles.activexxx来激活某个指定后缀的配置文件 application-evn1…

小程序项目实践(一)--项目的初始化以及前期的准备工作

目录 1.起步 1.1 uni-app 简介 1.2 开发工具 1.2.1 下载 HBuilderX 1.2.2 安装 HBuilderX 1.2.3 安装 scss/sass 编译 1.2.4 快捷键方案切换 1.2.5 修改编辑器的基本设置 1.3 新建 uni-app 项目 1.4 目录结构 1.5 把项目运行到微信开发者工具 1.6 使用 Git 管理项目 …

SpringBoot3响应式编程全套-R2DBC

目录 传送门前言一、R2DBC概念二、Spring Data R2DBC1、整合1.1、导入依赖1.2、编写配置 2、声明式接口&#xff1a;R2dbcRepository2.1、Repository接口2.2、自定义Converter2.3、配置生效 3、编程式组件 三、RBAC-SQL练习1、1-12、1-N 四、最佳实践五、附录 传送门 SpringMV…

python配合yolov11开发分类训练软件

上一篇文件写了用yolo分类模型开发分类软件&#xff0c;这边文章在上个分类软件的基础上加入训练功能环境配置:pycharm&#xff0c;PySide6 6.6.1 &#xff0c;PySide6-Addons 6.6.1&#xff0c;PySide6-Essentials 6.6.1&#xff0c;torch 2.3.1cu121&#xff0c;torchaudio 2…

Spring AI Java程序员的AI之Spring AI(三)RAG实战

Spring AI之RAG实战与原理分析 前言RAGDocumentDocumentReaderDocumentTransformerDocumentWriter VectorStoreSimpleVectorStoreRedisVectorStore元数据搜索组装提示词 前言 检索增强生成&#xff08;RAG&#xff09;是一种结合信息检索和生成模型的技术&#xff0c;用于将相…