TypeScript (一)运行环境配置,数据类型,可选类型,联合类型,type与interface,交叉类型,断言as,字面量类型,类型缩小
文章目录
- 一、认识TS
- 1.1 JS 存在的问题
- 1.2 TS的出现
- 1.3 TS运行环境
- 运行ts的三种方式
- 1.4 变量声明
- 1.5 类型推断
- 二、数据类型
- 2.1 JS数据类型
- (1) 数组Array
- (2) 对象Object
- (3) 其他类型
- 2.2 TS特有数据类型
- (1) any类型
- (2) unknown类型
- (3) void类型
- (4) never (了解)
- (5) tuple类型
- 三、语法细节
- 3.1 可选类型
- 3.2 联合类型
- 3.3 type与interface
- (1) 类型别名 type
- (2) 声明接口 interface
- (3) 区别
- 3.4 交叉类型
- 3.5 类型断言as
- 3.6 字面量类型
- 3.7 类型缩小 (Type Narrowing)
一、认识TS
1.1 JS 存在的问题
JS没有类型检测。
function getLength(str){return str.length;
}
console.log(getLength("abc")); // 正确调用,结果是3
console.log(getLength(123)); // 错误的调用,结果是undefined;
第五行代码在编写时不会报错,但是在运行过程中可能会出现TypeError: Cannot read property 'length' of undefined这类的错误。这是因为JS并不会对函数传入的参数进行限制,所以这个问题只会在运行时才被发现。进而影响后续代码的执行;
所以没有类型监测带来的问题:
- 代码不够安全、不够健壮。
- 没有类型约束,那么需要对别人传入的参数进行各种验证来保证我们代码的健壮性
- 我们去调用别人的函数,对方没有对函数进行任何的注释,我们只能去看里面的逻辑来理解这个函数需要传入什么参数, 返回值是什么类型;
1.2 TS的出现
TypeScript官网:TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
TypeScript是拥有类型的JavaScript超集,它可以编译成普通、干净、完整的JavaScript代码。
TS是加强版的JS,具有以下特点:
- JavaScript所拥有的特性,TypeScript全部都是支持的,
- 紧随ECMAScript的标准,所以ES6、ES7、ES8等新语法标准,它都是 支持的;
- TS增加了类型约束
- 不必考虑兼容性问题。TS最终会被编译成JS代码,编译时可以通过tsc或babel将其转为js(始于JS,归于JS)
1.3 TS运行环境
在.ts文件里编写TS不会出错,但是编译时需要搭建对应的环境,将其编译为JavaScript,才能够在浏览器上运行。
# 全局安装最新版本的 ts
npm install typescript -g# 检查版本,查看是否安装成功
tsc --version
运行ts的三种方式
(1) 方式一:
第一步: tsc 1.hello.ts ; 编译ts文件,生成1.hello.js文件
第二步:运行.js文件
每次修改完文件后,都要单独执行命令进行编译,然后再运行。很麻烦。
(2) 方式二:
- webpack配置(用脚手架创建文件的时候都会配置好,这里不细说)
(3) 方式三:
- 通过ts-node库 (接下来学习用这种方式来运行ts文件,)。
# 安装ts-node
npm install ts-node -g
# 安装ts-node需要的两个依赖包:tslib和@types/node
npm install tslib @types/node -g
# 运行ts文件,这种方式也不需要每次修改完之后单独执行命令进行编译,直接执行即可
ts-node hello.ts
注意:在使用ts-node运行代码时,控制台报错:Cannot find module ‘./hello.ts’
解决方法:添加export {}
// hello.ts
let message: string = "hello world"
console.log(message)
export {}
博客:使用ts-node命令运行ts文件时报错
1.4 变量声明
声明了类型后TypeScript就会进行类型检测,声明的类型可以称之为类型注解(Type Annotation);
(指明数据类型就是添加类型注解)
var/let/const 标识符:数据类型 = 赋值
将变量message声明为string类型:
let message:string = 'hello'
message = 123 // 将其他类型赋值给message会报错:不能将类型"number"分配给类型"string"
1.5 类型推断
类型推断:声明一个变量时,如果直接进行赋值, 会根据赋值的类型推导出变量(标识符)的类型注解。
let name='tom' // 推导出name的类型为string
name=123 // 这句赋值操作会报错:不能将“number”分配给类型"string"
let num = 123const msg = 123 // 推导出msg的类型为字面量类型123
const test:'Hello'='Hello' // 这里'Hello' 也是字面量类型

注:
- let声明的变量进行类型推导,推导出来的是通用类型(number、string之类的)
- const声明的变量进行类型推导,推导出来的是字面量类型
二、数据类型
TS是JS的一个扩展,原来JS拥有的东西,TS都有,包括JS里的八种数据类型,TS也是可以使用的。
接下来演示一下如何使用各种数据类型进行数据注解。
2.1 JS数据类型
(1) 数组Array
指定数组的类型注解,有两种写法
(1) string:[]——数组类型,并且数组里只能存string类型数据
const msg:string[]=["123","345","567"]
msg.push('hello')
(2) Array<string>——泛型写法,
const names :Array<string>=["tom","jerry"]
names.push(876) // 会报错
简写就是:
const name = ["tom","Lily","张三"]
name.push("jerry")
name.push(123) // 会报错
(2) 对象Object
info对象的类型就是红框里的样子

明确指定为对象类型的完整写法为:
const info:{name:string,age:number
}={name:'tom',age:18
}
还有一种写法,info:object={...},缺点是不能读取对象内的属性

(3) 其他类型
number类型:
// number数据类型,ts与js一致,不区分整数和浮点数
let num = 6.66;
num = 'tom' // 会报错
// ES6新增的各个进制的表示方法,ts也适用
num = 10; // 十进制
num = 0b110; // 二进制
num = 0o555; // 八进制
num = 0xf23; // 十六进制
boolean类型
let flag = true
flag =20 // 会报错
string类型
const name = "tom"
// ts也可使用ES6的模板字符串来拼接变量和字符串
const info = `my name is ${name}`
null与undefined类型
// 完整写法
let n:null = null
let u:undefined = undefined
// 简写
let n = null
let u = undefined
2.2 TS特有数据类型
(1) any类型
在某些情况下,无法确定某些变量的类型,且该变量的类型可能会发生改变时,可采用any类型。
let id:any = 987
id = 'tom'
id = {name:'why',age:10}
// 若需定义一个数组,但不确定元素类型,可定义为any:
const infos:any[] = ['123',123,{}]
这样其实是回归到原始的js了。
应用场景:
如果对于某些情况的处理过于繁琐不希望添加规定的类型注解,或者在引入一些第三方库时,缺失了类型注解,这个时候我们可以使用any。
(2) unknown类型
与any作用类似,在不确定类型的情况下也可以声明为unknown类型,区别是:
unknown类型的变量,不允许进行任何操作
let num:any=123
num = '123'
console.log(num+123); // any类型数据,不报错let result:unknown='tom'
result = 123 // 将number类型数据赋值给result不会报错
console.log(result.length); // 读取length属性,报错
因为不确定result的什么类型,读取length可能会出错,所以unknown类型数据不允许进行任何操作。
若想进行操作,则必须进行类型校验:
let result:unknown='tom'
result = 123
// 必须进行类型校验(类型缩小),才能根据缩小之后的类型,进行对应的操作
if (typeof result === 'string') {console.log(result.length);
}
(3) void类型
- 当一个函数没有return返回值的时候,其返回值就是void类型
// 未指明返回值类型,默认
function printID(id:string){console.log(id);
}
- 明确指明返回值类型是void;
function printID(id:string):void{console.log(id);return undefined // 对于返回值为void类型的函数,可以return undefined;// return 123 会报错,不能将number类型分配给void类型
}
-
(了解)基于上下文类型推导的函数,推导出返回类型是void时,并不会强制函数一定不能返回内容

但如果是自己编写的函数,明确指定是void类型,图片里13行的代码则会报错
(4) never (了解)
never 表示永远不会发生值的类型。开发中很少定义never类型。
应用场景: 进行类型推导时,可能会自动推导出never类型
function handleMsg(msg:string | number){switch(typeof msg){case "string":console.log(msg.length);break;case "number":console.log(msg+10);break;default:const check = msg // const check: never}
}
msg只可能是string或number类型,default语句不可能被执行到,所以check被推导为never类型。
(5) tuple类型
tuple元组类型。元组数据结构可以存放不同的数据类型,取出来的item也是有明确的类型
const msg:(string|number)[]=['tom',123,456]
const name = msg[0] // name类型是string|number,不能明确const info:[string,number,boolean]=["why",18,true] // 元素的类型应与声明的一一对应,比如第二个必须是number类型的数据,否则报错
const value = info[2] // value类型是boolean
- tuple和数组的区别:
- 数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中。
- 元组中每个元素都有自己特定的类型,根据索引值获取到的值可以确定对应的类型;
元组类型的应用:在函数中使用最多,尤其是函数的返回值中
// 将函数会返回值声明为tuple类型
function useState(initialValue:any):[number,(newValue:number)=>void]{
let stateValue = initialValue
function setValue(newValue:any){stateValue = newValue
}
return [stateValue,setValue]
}
const [count,setCount] = useState(10)
count() // 这行代码会报错,count类型是number,错误的使用会及时提醒
setCount(100)
但若未明确指定返回值的类型,则推导为any类型的数组:

此时count()语句不合法,但没有错误提示,则代码是不安全的。
三、语法细节
3.1 可选类型
可以指定某个对象中某个属性是否是可选的(可以不传),语法就是加个问号?
function printPoint(point: { x: number; y: number; z?: number }) {console.log(point.x)console.log(point.y)console.log(point.z)
}// printPoint({ x: 123}) // 报错,因为y是必传的但没传
printPoint({ x: 123, y: 321 }) // 123 321 undefined
printPoint({ x: 123, y: 321, z: 111 }) // 123 321 111
3.2 联合类型
TS中,我们可以使用运算符从现有类型中构建新类型
联合类型(Union Type):有两个或更多其他类型组成的新类型;表示变量类型可以是这些类型中的任意一个。
// foo可以是number类型,也可以是string类型
let foo : number | string = "abc"
foo = 123
给一个联合类型的变量赋值:只要保证是联合类型中的某一个类型的值即可。拿到值之后,最好需要进行类型缩小,判断出更具体的数据类型,再进行下一步的操作。
function printId(id:string|number){// 类型缩小if (typeof id === 'string') {console.log('id是',id.toUpperCase());}else {console.log('id是',id);}
}
printId(123) // id是123
printId('tom') // id是TOM
3.3 type与interface
(1) 类型别名 type
某些类型名字很长,且在多处使用,可以给该类型起一个别名。
比如:
type IDtype = number | string
function printId(id:IDtype) {...}
//等价于
function printId(id:number | string) {...}
再比如:
type PointType = {x:number,y:number,z?:number
}
function printPoint(point: PointType) {...}
// 等价于
function printPoint(point: {x:number,y:number,z?:number}) {...}
起别名之后,可读性会更强一点,使用也更方便一点。
(2) 声明接口 interface
interface的作用和type相似,都可以用来 给对象类型起别名。interface的使用方式为:
// 通过接口interface 创建某种对象类型----是一种声明的方式
interface PointType{x:number,y:number,z:number}
// 别名type创建某种对象类型----是一种赋值的方式type PointType = {x:number,y:number,z:number
}
接口的几乎所有特性都可以在 type 中使用。
(3) 区别
-
一、type类型的使用范围更广,接口类型只能用来声明对象
type MyNumber = number type IDtype = number | string -
二、声明对象时,interface可以多次声明,
-
type不允许有两个相同名称的别名
type PointType = {x:numbery:number } type PointType ={ // 提示标识符PointType重复z:number } -
interface可以多次声明同一个接口
interface PointType{x:numbery:number } interface PointType{z:number } // 这几次声明里的条件,该类型的变量都需要满足 const point:PointType={x:20,y:20,z:40 }
-
-
三:interface支持继承
interface IAnimal{name:string,age:number } interface IDog extends IAnimal{color: string } // 变量dog需要给这三个属性都赋值 const dog: IDog={name:'tom',age:2,color:'red' } -
四、interface可以被类实现(涉及到TS面向对象)
class Person implements IAnimal{}
总结:从代码的扩展性角度来说,如果是对象类型的声明,应使用interface,非对心类型的定义应使用type。
3.4 交叉类型
联合类型:值为多个类型中的一个即可
交叉类型:需要同时满足多个类型的条件,使用&
type MyType = string & number
上述代码的含义是MyType类型的变量既是string,又是number;不可能存在这样的数据,所以:交叉类型通常是对对象类型进行交叉的:
interface IMan{name:string,age:number
}
interface ICoder{name:stringcoding:()=>void
}
type NewType = IMan & ICoder
const obj: NewType={name:'tom',age:23,coding(){console.log('coding');}
}
3.5 类型断言as
在确定具体类型时,直接使用类型断言来指明类型,减少类型缩小代码的编写。
// 当选择标签选择器时,ele和ele2的类型是确定的
const ele = document.querySelector('div') // const ele: HTMLDivElement
const ele2 = document.querySelector('img') // const ele2: HTMLImageElement
ele2.src="..." //且可以给src属性赋值// 采用类选择器时,ele3的类型则是const ele3: Element,没那么具体了
const ele3 = document.querySelector('.img')
ele3.src="" // 会报错,提示Element不存在属性src
如果我们确定ele3一定是HTMLImageElement类型,则可以使用断言来具体类型
const ele3 = document.querySelector('.img') as HTMLImageElement
ele3.src="" // 断言之后也不会报错
TypeScript只允许类型断言转换为 更具体 或者 不太具体 的类型版本,
// 代码本身不正确,不建议这样写。这里是为了说明应断言为更加具体或不太具体的类型
const age:number = 18
const age1 = age as any // 断言为不太具体的类型 number->any
const age2 = age1 as string // 断言为更具体地类型 any->string
console.log(age2.length);// number断言为string类型,会报错
const age3 = age as string
3.6 字面量类型
字面量类型(literal types)
// const类型的变量可自动推断为字面量类型; let也可以声明字面量类型的变量
const name = 'tom' // name类型为"tom"
let name2:'tom' = 'tom' // name2类型为"tom"
// 字面量类型的应用通常是将多个字面量类型联合
type Direction = "left" | "right" | "up" | "down"
const d1: Direction = "left"
案例:
const info={url:"xxx",method:"GET"
}
function request(url:string,method:"GET"|"POST"){console.log(url,method);
}request(info.url,info.method) // 会报错
原因:method的类型是string,值是GET;而request函数要求参数method的类型是"GET"或者"POST"
解决:
// 方案一:类型断言
request(info.url,info.method as "GET")// 方案二:直接让info对象类型是一个字面量类型
const info={url:"xxx",method:"GET"
} as const
request(info.url,info.method)

为什么xxx也可以,因为xxx本身是一个string(不懂)
3.7 类型缩小 (Type Narrowing)
类型缩小有以下几种方式:typeof、平等缩小(===,!=)、instance of、in、等。。
-
typeof
function printId(id:number|string){if (typeof id === 'string') {console.log(id.toUpperCase());}else{console.log(id);} } -
平等缩小 ,主要用于字面量类型
type Direction = "left" | "right"function turnDirection(direction:Direction){switch(direction){case 'left':console.log('left'); break;case 'right':console.log('right'); breakdefault:console.log('调用默认方法'); }} -
instanceof 检查是否为另一个值的实例
function printValue(date: Date | string) {if (date instanceof Date) {console.log(date.toLocaleDateString());}else{console.log(date);} }if语句里也可以用typeof, 但是
typeof date === 'Date'是不对的; Date 属于object 可以写成typeof date === 'object' -
in用于确定对象是否具有某个属性

相关文章:
TypeScript (一)运行环境配置,数据类型,可选类型,联合类型,type与interface,交叉类型,断言as,字面量类型,类型缩小
文章目录 一、认识TS1.1 JS 存在的问题1.2 TS的出现1.3 TS运行环境运行ts的三种方式 1.4 变量声明1.5 类型推断 二、数据类型2.1 JS数据类型(1) 数组Array(2) 对象Object(3) 其他类型 2.2 TS特有数据类型(1) any类型(2) unknown类型(3) void类型(4) never (了解)(5) tuple类型 …...
Linux Find 命令详情解释
文件查找 普通查询find /etc -maxdepth 1 -type f -name "pa*"命令 目录... 查找深度 类型 文件名称包含 # -type文件类型:f表示文件,不指定类型的话,文件和目录都会查找# -maxdepth查找深度:目录层级的意思࿰…...
2024年认证杯SPSSPRO杯数学建模A题(第一阶段)保暖纤维的保暖能力全过程文档及程序
2024年认证杯SPSSPRO杯数学建模 A题 保暖纤维的保暖能力 原题再现: 冬装最重要的作用是保暖,也就是阻挡温暖的人体与寒冷环境之间的热量传递。人们在不同款式的棉衣中会填充保暖材料,从古已有之的棉花、羽绒到近年来各种各样的人造纤维。不…...
Milvus python库 pymilvus 常用操作详解之Collection(下)
上篇博客 Milvus python库 pymilvus 常用操作详解之Collection(上) 主要介绍了 pymilvus 库中Collection集合的相关概念以及创建过程的代码实现,现在我们要在该基础上实现对于collection中插入数据的混合检索(基于dense vector 和…...
李飞飞:Agent AI 多模态交互的前沿探索
发布于:2024 年 11 月 27 日 星期三 北京 #RAG #李飞飞 #Agent #多模态 #大模型 Agent AI在多模态交互方面展现出巨大潜力,通过整合各类技术,在游戏、机器人、医疗等领域广泛应用。如游戏中优化NPC行为,机器人领域实现多模态操作等。然而,其面临数据隐私、偏见、可解释性…...
[October 2019]Twice SQL Injection
有一个登录框和一个注册页面,题目也说这个是二次注入,那么就用二次注入的payload就行 1 union select database()# //爆库 1 union select group_concat(table_name) from information_schema.tables where table_schemactftraining# //爆表 1 union …...
Python爬虫——城市数据分析与市场潜能计算(Pandas库)
使用Python进行城市市场潜能分析 简介 本教程将指导您如何使用Python和Pandas库来处理城市数据,包括GDP、面积和城市间距离。我们将计算每个城市的市场潜能,这有助于了解各城市的经济影响力。 步骤 1: 准备环境 确保您的环境中安装了Python和以下库&…...
如何搭建JMeter分布式集群环境来进行性能测试
在性能测试中,当面对海量用户请求的压力测试时,单机模式的JMeter往往力不从心。如何通过分布式集群环境,充分发挥JMeter的性能测试能力?这正是许多测试工程师在面临高并发、海量数据时最关注的问题。那么,如何轻松搭建…...
【Halcon】 derivate_gauss
1、derivate_gauss Halcon中的derivate_gauss算子是一个功能强大的图像处理工具,它通过将图像与高斯函数的导数进行卷积,来计算各种图像特征。这些特征在图像分析、物体识别、图像增强等领域具有广泛的应用。 参数解释 Sigma:高斯函数的标准差,用于控制平滑的程度。Sigma…...
stm32中systick时钟pinlv和系统节拍频率有什么区别,二者有无影响?
在STM32中,SysTick时钟频率和系统节拍频率是两个不同的概念,它们之间存在区别,并且这种区别会对系统的运行产生一定的影响。以下是对这两个概念的详细解释以及它们之间关系的探讨: 一、SysTick时钟频率 定义:SysTick…...
柔性数组详解+代码展示
系列文章目录 🎈 🎈 我的CSDN主页:OTWOL的主页,欢迎!!!👋🏼👋🏼 🎉🎉我的C语言初阶合集:C语言初阶合集,希望能…...
前端入门指南:Webpack插件机制详解及应用实例
前言 在现代前端开发中,模块化和构建工具的使用变得越来越重要,而Webpack作为一款功能强大的模块打包工具,几乎成为了开发者的默认选择。Webpack不仅可以将各种资源(如JavaScript文件、CSS文件、图片等)打包成优化后的…...
C++备忘录模式
在读《大话设计模式》,在此记录有关C实现备忘录模式。 场景引入:游戏中的存档,比如打boss之前记录人物的血量等状态。 下面代码是自己根据理解实现的存档人物血量功能。 #include <iostream>using namespace std;//声明玩家类 class …...
【Electron学习笔记(四)】进程通信(IPC)
进程通信(IPC) 进程通信(IPC)前言正文1、渲染进程→主进程(单向)2、渲染进程⇌主进程(双向)3、主进程→渲染进程 进程通信(IPC) 前言 在Electron框架中&…...
Java 中的 remove 方法深度解析
在 Java 编程中,remove方法是一个经常被使用的操作。它可以用于从各种数据结构中移除特定的元素,帮助我们有效地管理和操作数据。本文将深入探讨 Java 中的remove方法,包括在不同数据结构中的应用、使用场景、注意事项以及性能考虑等方面。 …...
企业品牌曝光的新策略:短视频矩阵系统
企业品牌曝光的新策略:短视频矩阵系统 在当今数字化时代,短视频已经渗透到我们的日常生活之中,成为连接品牌与消费者的关键渠道。然而,随着平台于7月20日全面下线了短视频矩阵的官方接口,许多依赖于此接口的小公司和内…...
【初阶数据结构与算法】二叉树顺序结构---堆的应用之堆排、Top-K问题
文章目录 一、堆排引入之使用堆排序数组二、真正的堆排1.向上调整算法建堆2.向下调整算法建堆3.向上和向下调整算法建堆时间复杂度比较4.建堆后的排序4.堆排序和冒泡排序时间复杂度以及性能比较 三、Top-K问题 一、堆排引入之使用堆排序数组 在了解真正的堆排之前,我…...
vue3 + ts 使用 el-tree
实现效果: 代码: <template><!-- el-tree 使用 --><div class"my-tree-container"><el-scrollbar height"100%"><el-tree ref"treeRef" :data"treeData" node-key"id" n…...
Create Stunning Word Clouds with Ease!
Looking to craft breathtaking word clouds? WordCloudStudio is your go-to solution! Whether you’re a marketer, educator, designer, or simply someone who loves visualizing data, this app has everything you need. Download now: https://apps.apple.com/app/wor…...
html+css网页设计 旅游 马林旅行社5个页面
htmlcss网页设计 旅游 马林旅行社5个页面 网页作品代码简单,可使用任意HTML辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 获取源码 1&#…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...
2.2.2 ASPICE的需求分析
ASPICE的需求分析是汽车软件开发过程中至关重要的一环,它涉及到对需求进行详细分析、验证和确认,以确保软件产品能够满足客户和用户的需求。在ASPICE中,需求分析的关键步骤包括: 需求细化:将从需求收集阶段获得的高层需…...
