TypeScript基础入门(一、常用类型)

目录

第一章 前言

1.1 介绍TypeScript

1.2 TypeScript相比Js的优势

1.3 使用TypeScript的准备工作

第二章 TypeScript的数据类型

2.1 TypeScript的常用类型

2.1.1 概述

2.1.2 TS使用JS基本数据类型

2.1.2.1 number

2.1.2.2 string

2.1.3.3 boolean

2.1.2.4 null

2.1.2.5 undefined

2.1.2.6 symbol

2.1.2.7 总结

2.1.3 TS使用JS引用数据类型

2.1.3.1 数组(array)

2.1.3.2 函数(function)

2.1.3.3 对象(object)

2.1.4 联合数据类型 

2.1.5 类型别名(type)

2.1.6 接口(interface)

2.1.6.1 类型别名与接口的区别

2.1.6.2  接口继承(extends)

2.1.7 元组(tuple)

2.1.8 类型推论

2.1.9 类型断言(as)

2.1.10 字面量类型(const)

2.1.11 枚举(enum)

2.1.12 any类型

2.1.13 typeof


第一章 前言

1.1 介绍TypeScript

  • TypeScript(简称:TS)是 JavaScript 的超集(JS 有的 TS 都有)。
  • 从编程语言的动静来区分,TypeScript 属于静态类型的编程语言,JS 属于动态类型的编程语言。 静态类型:编译期做类型检查; 动态类型:执行期做类型检查。 代码编译和代码执行的顺序:先编译再执行。​​​​​​
  • 由于TS,在编译时就开始做类型检查了,所以TS 可以提前到在编写代码的同时就发现代码中的错误,减少找 Bug、改 Bug 时间

1.2 TypeScript相比Js的优势

  • 更早(写代码的同时)发现错误,减少找 Bug、改 Bug 时间,提升开发效率。
  • 程序中任何位置的代码都有代码提示,随时随地的安全感,增强了开发体验。
  • 强大的类型系统提升了代码的可维护性,使得重构代码更加容易
  • 支持最新的 ECMAScript 语法,优先体验最新的语法,让你走在前端技术的最前沿。
  • TS 类型推断机制,不需要在代码中的每个地方都显示标注类型,让你在享受优势的同时,尽量降低了成本。

1.3 使用TypeScript的准备工作

  • 安装ts 的工具包,原因:(浏览器与node只认识js代码,不认识ts代码,安装ts的工具包目的是将ts转为js)
npm i -g typescript

利用tsc -v查看是否安装成功

tsc -v

 

使用顺序 :

  1. 例如:创建 hello.ts 文件(注意:TS 文件的后缀名为 .ts
  2. 将 TS 编译为 JS:在终端中输入命令,tsc hello.ts(此时,在同级目录中会出现一个同名的 JS 文件)
  3. 执行 JS 代码:在终端中输入命令,node hello.js
  • 使用 ts-node 包,直接在 Node.js 中执行 ts 代码
npm i -g ts-node

利用ts-node -v查看是否安装成功

ts-node -v

使用顺序:直接ts-node hello.ts

第二章 TypeScript的数据类型

2.1 TypeScript的常用类型

2.1.1 概述

  • 可以将 TS 中的常用基础类型细分为两类:JS 已有类型 与 TS 新增类型。
  • JS已有数据类型:基本数据类型与引用数据类型
  1. 基本数据类型:number、string、boolean、null、undefined、symbol
  2. 引用数据类型:object(包括:数据array、函数function、对象等)
  • TS新增类型
  1. 自定义类型(类型别名)、联合类型、接口、元组、自变量类型、枚举、void、any等等

2.1.2 TS使用JS基本数据类型

2.1.2.1 number
let number: number = 23
2.1.2.2 string
let myName: string = '关注ve'
2.1.3.3 boolean
let isYouth: boolean = true
2.1.2.4 null
let a: null = null
2.1.2.5 undefined
let b: undefined = undefined
2.1.2.6 symbol
let s: symbol = Symbol()
2.1.2.7 总结
  • 写法:  变量 :数据类型 = 类型值
  • 通过数据类型为变量进行约束,从而只能给变量赋值该类型的值
  • 代码中查看数据的数据类型:(鼠标悬浮在查看的变量上)

  • 当赋值其他类型是报错,例如

2.1.3 TS使用JS引用数据类型

2.1.3.1 数组(array)
  • 写法一:变量:数据类型[] = ['该数据类型的值1','该数据类型值2'……]——(推荐)
const numbers: number[] = [1,2,4,5] // 该写法是一个纯数字数组数据类型,数组内只包含数字类型
const strs: string[] = ['1','2','3'] // 数组内只包含字符串类型
  • 写法二:变量:Array<数据类型> = ['该数据类型的值1','该数据类型值2'……]
const numbers2: Array<number> = [1,2,4,5]
const strs2: Array<string> = ['1','2','3']
  • 解释:针对于以上两种方法,只能定义一个数组,然后数组的值只能是纯规定数据类型的值,数组中不能又其他类型的值
  • 需求:如果一个数组中能有nuber、 string、boolean等多个数据类型在同一个数组中
  • 解决:联合数据类型: 变量: (数据类型)[] = [字面量,……](后续会对该类型具体解释)
const arr: (number | string | null | boolean)[] = [1,'a',false, null] 
// 该写法将|理解成或者,表示arr变量是一个数组,数组里面的值可以有数据类型、字符串类型、null、boolean
2.1.3.2 函数(function)
  • 说到函数,我们可以知道有参数和返回值两种
  •  写法一:单独指定参数、返回值的类型
  1.  普通函数:function 函数名 (参数1: 参数类型, 参数2: 参数类型…): 函数返回数据类型 {}
  2. 箭头函数:const 函数名 = (参数1: 参数类型, 参数2: 参数类型…): 函数返回数据类型 => {}
function add (number1:number, number2: number): number { // 普通函数
    return number1 + number2
}
console.log(add(1,2))
const addFn = (number1:number, number2: string): string => { // 箭头函数
    return number1 + number2
}
console.log(addFn(2,'fv'))
  • 写法二:同时指定参数、返回值的类型(这种方法适用于箭头函数)
  1. const 函数名: (参数1: 参数类型,参数2: 参数类型…) => 函数返回数据类型 = (参数1,参数2) => {}

// 只适用于函数表达式,例子:
const addFn: (number1:number, number2: string) => string = (number1,number2) => {
    return number1 + number2
}
  • 如果函数没有返回值,那么,函数返回值类型为:void

function returnvoid(number:number): void {
    console.log("函数返回空值", number)
}
returnvoid(2222)
  • 使用函数实现某个功能时,参数可以传也可以不传。这种情况下,在给函数参数指定类型时,就用到可选参数了。

  1. 可选参数: 在可传可不传的参数名称后面添加 ?(问号)

  2. 注意:必填参数必须在可选参数之前

function mySlice(start:number,end?:number):void {
    console.log("开始:" + start + '结束' + end )
}
mySlice(1)
mySlice(1,6)
2.1.3.3 对象(object)
  • JS中的对象是由属性和方法构成的,而TS 中对象的类型就是在描述对象的结构(有什么类型的属性和方法)。
  1. 直接使用{}来描述对象结构。属性采用属性名: 类型的形式方法采用方法名(): 返回值类型的形式
  2. 如果方法有参数,就在方法名后面的小括号中指定参数类型(比如: greet(name: string): void )
  3. 在一行代码中指定对象的多个属性类型时,使用; / ,( 分号或者逗号) 来分隔

        - 如果一行代码只指定一个属性类型( 通过换行来分隔多个属性类型),可以去掉;(分号)。

        - 方法的类型也可以使用箭头函数形式(比如 :{sayHi: () => void1}

// 写法例子
let person: {
    name: string,
    age: number, 
    say:() => void,
    greet(name:string):void
} = {
    name: '李四',
    age: 18,
    // 注意:我们这里最好是跟上面描述的写法写,便于阅读,当然这么写也不会错
    // say(){
    //     console.log("说hello")
    // },
    // greet:(name) => {
    //     console.log("和" + name + "说hello")
    // }
    say:() => {
        console.log("说hello")
    },
    greet(name) {
        console.log("和" + name + "说hello")
    }
}
person.say()
person.greet('zs')
console.log(person.name,person.age)

// 写在一行
// let person: {name: string, age: number, say(name:string):void} = {
//     name: '李四',
//     age: 18,
//     say(name) {
//         console.log("和" + name + "说hello")
//     }
// }

2.1.4 联合数据类型 

  • 联合数据类型:由两个或者多个其他类型组成的类型,表示可以是这些类型中的任意一种

  • 利用 | 连接多个数据类型,| 可理解或者

  • 写法:变量: (数据类型1,数据类型2…)[] = [字面量,……]

// 该写法将|理解成或者,表示arr变量是一个数组,数组里面的值可以有数据类型、字符串类型、null、boolean
const arr: (number | string | null | boolean)[] = [1,'a',false, null] 
//该写法表示data可以是number类型、纯字符串数组、存在null/boolean的数组
const data: number | string[] | (null | boolean)[] =  ['111']

2.1.5 类型别名(type)

  • 类型别名( 自定义类型 ) : 为任意类型起别名

  • 使用场景: 当同一类型(复杂 )被多次使用时,可以通过类型别名,简化该类型的使用。

  • 使用方法:

  1. 使用 type 关键字来创建类型别名

  2. 类型别名(比如:a,b…但是最好语义化一些),可以是任意合法的变量名称

  3. 创建类型别名后,直接使用该类型别名作为变量的类型注解即可

type CustomArray = (number | string)[]
const array1: CustomArray = [1,2,'a','v']
const array2: CustomArray = [2,'a','b']

type a = (number | string)[] | number
const array3: a = [1,2,'a','v']
const array4: a = [2,'a','b']
const number: a = 20

2.1.6 接口(interface)

  • 当一个对象类型被多次使用时,一般会使用接口 (interface )来描述对象的类型,达到复用的目的

  • 使用方法:

  1. 使用 interface 关键字来声明接口。

  2. 接口名称(比如:a,b…但是最好语义化一些 ),可以是任意合法的变量名称

  3. 声明接口后,直接使用接口名称作为变量的类型

// 使用接口 -> 这里是两个对象使用的相同键值对以及类型
interface IPerson {
    name: string
    age: number, 
    say:() => void,
    greet(name:string):void
}
let person1: IPerson = {
    name: '张三',
    age: 18,
    say(){
        console.log("说hello")
    },
    greet:(name) => {
        console.log("和" + name + "说hello")
    }
}
let person2: IPerson = {
    name: '李四',
    age: 18,
    say(){
        console.log("说hello")
    },
    greet:(name) => {
        console.log("和" + name + "说hello")
    }
}
// 多个对象有共同的键值对
// let person1: {
//     name: string
//     age: number, 
//     say:() => void,
//     greet(name:string):void
// } = {
//     name: '李四',
//     age: 18,
//     say(){
//         console.log("说hello")
//     },
//     greet:(name) => {
//         console.log("和" + name + "说hello")
//     }
// }

// let person2: {
//     name: string
//     age: number, 
//     sex: string,
//     say:() => void,
//     greet(name:string):void
// } = {
//     name: '李四',
//     age: 18,
//     sex: '男',
//     say(){
//         console.log("说hello")
//     },
//     greet:(name) => {
//         console.log("和" + name + "说hello")
//     }
// }
2.1.6.1 类型别名与接口的区别
  • 相同点:都可以给对象指定类型

  • 不同点:

  1. 接口(interface)只能给对象指定类型,而类型别名(type)不仅可以给对象指定类型也可以给为任意类型指定别名

  2. 写法上接口(interface)类似于声明函数,函数中是不同属性/方法的类型描述,而类型别名(type)类似于赋值类型

interface IPerson {
    name: string
    age: number, 
    say:() => void,
    greet(name:string):void
}

type IPerson = {
    name: string
    age: number, 
    say:() => void,
    greet(name:string):void
}

type newarr = number | string
2.1.6.2  接口继承(extends)
  • 两个接口之间有相同的属性或方法,可以 将公共的属性或方法抽离出来,通过继承来实现复用
interface Point2D {
  x: number
  y: number
}
// interface Point3D { x: number; y: number; z: number } // 其中x, y是与point2D的x, y相同

// 使用 继承 实现复用:
interface Point3D extends Point2D {
  z: number
}

let p3: Point3D = {
  x: 1,
  y: 1,
  z: 0
}

2.1.7 元组(tuple)

  • 场景:在一些特殊情况下,例如地图坐标:使用经纬度坐标来标记位置信息。
  • 1、如果我们使用如下方法定义一个数组:
let position: number[]

我们从之前的方法可以知道,这其实定义的是一个纯数字类型的数组,长度任意长

let position: number[] = [39, 114, 1, ,3, 4]

但是,我们实际需要得到的是坐标信息,只需要有经纬度的值就可以了,如果使用以上方法,后面的值就没有意义了

  • 2、使用元组类型
let position: [number, string] = [39, '114']

 -- 元组:确切的控制了这个数据有多少个元素,以及元素的类型;

-- 该例子是定义了一个变量有两个元素,第一个元素是number数据类型,第二个是string类型;

-- 如果赋值多了会报错,不对应赋值也会报错,如下所示

2.1.8 类型推论

  • ts中在某些没有明确指出类型的地方,ts的类型推论机制会帮助提供类型
  • 常见场景:1.声明变量并初始化时,2.决定函数返回值时

  • 但是如果声明变量没有立即初始化,则必须添加类型注解

否则:

2.1.9 类型断言(as)

  • 指定更具体的类型
  1. as关键字
  2. 关键字as后面是一个更加具体的类型
const aLink = document.getElementById('link') as HTMLAnchorElement
  • 使用<>语法,这种语法形式不常用:(与react语法冲突,不常用
const aLink = <HTMLAnchorElement>document.getElementById('link')
  •  获取具体元素的方法:在浏览器控制台,先选中元素,此时元素后面会被添加$0,通过 console.dir() 打印该 DOM 元素,在属性列表的最后面,即可看到该元素的类型。

2.1.10 字面量类型(const)

  • 初体验,代码如下:
let str1 = 'hello'
const str2 = 'hello'

  1. 根据类型推论我们可以发现,str1与str2的类型分别是string与 'hello'
  2. str1 是一个变量(let),它的值可以是任意字符串;而str2 是一个常量(const),它的值不能变化只能是 'hello'​​​​​​​
  • 除字符串外,任意的 JS 字面量(比如,对象、数字等)都可以作为类型使用

  • 使用场景:表示一组明确的可选值列表一般搭配联合类型一起使用,例如:

2.1.11 枚举(enum)

  • 类似字面量类型+联合类型组合的功能用来表示一组明确的可选值
  • 初体验,代码如下:
enum Direction { Up,Down,Right,Left }

function changeDirection(direction: Direction) {
    return direction
}

console.log(changeDirection(Direction.Up))

-- 输出结果: 

-- 扩展1:

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

-- 总结:

  1. 使用enum关键字定义枚举
  2. 约定枚举名称、枚举中的值以大写字母开头
  3. 枚举中的多个值之间通过 ,(逗号)分隔
  4. 定义好枚举后,形参直接使用枚举名称作为类型注解
  5. 实参的值可以是枚举 Direction 成员的任意一个,接通过点(.)语法访问枚举的成员
  6. 从输出结果为0,我们可以知道表示枚举的值是会携带默认值的,从 0 开始自增的数值
  7. 通过扩展1能知道数字的起始值可以自定义,并且自增只针对数字类型
  8. 枚举中的成员也可以自定义初始化值
  • 字符串枚举 :枚举成员的值是字符串
enum Direction { Up = 'up', Down = 'down', Right = 'right', Left = 'left'}

function changeDirection(direction: Direction) {
    return direction
}

console.log(changeDirection(Direction.Up))

  1. 注意: 字符串枚举没有自增长行为,因此,字符串枚举的每个成员必须有初始值
  • 转换为js文件

  1.  由于其他类型仅仅被当做类型,而枚举不仅用作类型,还提供值枚举不仅作为类型,还提供值);所有其他类型会在编译成js是自动移除,但是枚举会被编译成js代码;
  2. 一般情况下, 推荐使用字面量类型+联合类型组合的方式 ,相比枚举更加直观、简洁、高效。

2.1.12 any类型

  • 不推荐使用,当值为any类型时,可以对改值进行任意操作,并且不会有代码提示;也不会有报错,失去了ts的意义

  • 其他隐式具有any类型情况:1 声明变量不提供类型也不提供默认值  2 函数参数不加类型

2.1.13 typeof

  • 初使用:
let number1: number = 10
let number2 = typeof number1
console.log(number2)
let obj1 = {x: 1, y: 2}
let obj2 = typeof(obj1)
console.log(obj2)
function dot(point: { x: number, y: number }) {
    return point
}
console.log(dot(obj1))
function dot2(point: typeof obj1) {
    return point
}
console.log(dot2(obj1))

  1. 使用场景:根据已有变量的值,获取该值的类型,来简化类型书写
  2. 如果直接使用typeof,获取的就是获取变量的类型,如上前两个输出
  3. typeof 出现在类型注解的位置(参数名称的冒号后面)所处的环境就在类型上下文(区别于 JS 代码),如上最后一个输出。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pytorch DistributedDataParallel(DDP)教程一:快速入门理论篇

Pytorch DistributedDataParallel&#xff08;DDP&#xff09;教程一&#xff1a;快速入门理论篇 目录 一、 写在前面二、什么是分布式并行训练1. 并行训练2. 数据并行 三、DDP的基本原理1. DDP的训练过程2. Ring-All-Reduce算法 四、如何搭建一个Pytorch DDP代码框架1. 与DDP有…

二次元AI绘画生成器免费:教你生成精美图片

二次元AI绘画生成器&#xff0c;无疑是现代技术与艺术完美结合的典范。这些工具不仅将复杂的绘画过程简化&#xff0c;更让每一个艺术爱好者的创意得以充分展现。这些生成器能够精准捕捉大家的创意精髓&#xff0c;将其转化为细腻、独特的二次元画作。无论是角色设计、场景描绘…

OpenHarmony UI动画-box2d

简介 用于游戏开发&#xff0c;使物体的运动更加真实&#xff0c;让游戏场景看起来更具交互性&#xff0c;比如愤怒的小鸟 效果展示 下载安装 ohpm install ohos/box2dOpenHarmony ohpm环境配置等更多内容&#xff0c;请参考 如何安装OpenHarmony ohpm包 使用说明 import * …

OCR图片转化为Excel文件功能在哪些平台和设备上能实现?

在现今数字化时代&#xff0c;将图片转化为Excel文件已成为许多工作者和研究者的重要需求。这种转换功能在多个平台和设备上均能实现&#xff0c;为用户提供了极大的便利。 首先&#xff0c;我们来看看在线平台方面。目前&#xff0c;市面上有许多在线工具可以将图片转换为Exc…

MoJoCo 入门教程(七)XML 参考

系列文章目录 前言 表格第二列中的符号含义如下&#xff1a; ! 必填元素&#xff0c;只能出现一次 ? 可选元素&#xff0c;只能出现一次 * 可选元素&#xff0c;可多次出现 R 可选元素&#xff0c;可递归出现多次 一、简介 本章是 MuJoCo 中使用的 MJCF 建模语言的参考手册。…

【云计算】安全组和网络ACL的区别

安全组和网络ACL的区别 ACL&#xff08;Access Control List&#xff09;和 安全组&#xff08;Security Group&#xff09;是两种不同的网络安全控制机制&#xff0c;通常用于管理云计算平台中的网络访问权限。它们在功能和实现上有一些显著的区别&#xff1a; 辨析 范围不同&…

如何把网易云ncm转换为mp3格式

大家在网易云下载音乐的时候会发现下载的音乐格式是ncm&#xff0c;这个格式只能在网易云播放器才能播放&#xff0c;无法在别的播放器上播放。今天教大家把ncm转换为更加通用的格式 打开智游剪辑&#xff08;官网: zyjj.cc&#xff09;&#xff0c;搜索ncm转mp3 这里就只需要上…

DC电源模块的未来发展方向和创新应用领域

BOSHIDA DC电源模块的未来发展方向和创新应用领域 随着科技的快速发展&#xff0c;直流&#xff08;DC&#xff09;电源模块的应用领域也在不断扩大。从传统的电子产品到新兴的清洁能源领域&#xff0c;DC电源模块正发挥着越来越重要的作用。未来&#xff0c;DC电源模块将继续…

windows docker desktop==spark环境搭建

编写文件docker-compose.yml version: 3services:spark-master:image: bde2020/spark-master:3.1.1-hadoop3.2container_name: spark-masterports:- "8080:8080"- "7077:7077"- "2220:22"volumes:- F:\spark-data\m1:/dataenvironment:- INIT_D…

android studio gradle 下载不下来的问题

有时候由于网络问题&#xff0c;会发现 android-studio 或 idea 下载不懂 gradle&#xff0c;可以修改 gradle-wrapper.properties 配置文件中的 distributionUrl 选项来解决这个问题。 distributionUrlhttps\://mirrors.cloud.tencent.com/gradle/gradle-5.1.1-all.zip 这个选…

【七 (2)FineBI FCP模拟试卷-平台新增用户留存分析】

目录 文章导航一、字段解释1、用户平台登录信息表格2、用户平台激活信息表格 二、需求三、操作步骤1、建立用户平台登录信息表格和用户平台激活信息表格的关联关系2、将用户平台激活信息表格的激活日期添加到用户平台登录信息表格3、新增公式列&#xff0c;计算激活时间和登录时…

【ACM列表推荐会议 | EI稳定检索】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)

2024年第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Automation and High Performance Computing 2024第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)将于20…

JVM虚拟机(十)Java内存泄漏的排查思路

目录 一、可能产生内存泄露的地方二、复现堆内存泄漏三、如何排查堆内存问题&#xff1f;3.1 获取对内存快照 dump3.2 使用 Visual VM 去分析 dump 文件3.3 定位内存溢出问题 一、可能产生内存泄露的地方 在进行排查 Java 的内存泄漏问题之前&#xff0c;首先我们要知道哪里可…

数据可视化-ECharts Html项目实战(12)

在之前的文章中&#xff0c;我们深入学习ECharts特殊图表中的矩形树图以及Echarts中高级功能的多图表联动。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 数…

通过IP地理位置阻止网络攻击:有效性与局限性

网络攻击已成为当今互联网世界中的一项常见挑战。黑客和恶意用户利用各种手段对网络系统进行攻击&#xff0c;造成数据泄露、服务中断甚至财产损失。在这种背景下&#xff0c;寻找有效的网络安全解决方案变得至关重要。 IP地理位置阻止是一种基于黑名单的网络安全措施。它的原…

最新SpringBoot项目财务管理系统

采用技术 最新SpringBoot项目财务管理系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 系统登录页面 管理员功能 管理员功能页面 员工管理页面 部…

Python采集海外电影信息,Roxlabs全球IP代理轻松搞定

一、为什么要学会应用 IP 代理技术二、采集海外电影信息爬虫实战2.1 选择目标网站并生成代理2.2 编写爬虫并设置代理2.3 运行爬虫2.4 处理数据2.5 完整代码 三、Roxlabs 代理及优势分析四、快速应用Roxlabs代理功能4.1 领免费流量4.2 代理类型4.3 获取代理4.4 配置代理设置4.5 …

进销存是什么?怎么快速上手制作进销存报表?

在现代商业运营中&#xff0c;进销存管理是企业持续稳健发展的关键组成部分。为了更好地把握库存状况、合理调配资源、提高决策效率&#xff0c;企业采用进销存报表是一种极为有效的手段。本文将从进销存的基本概念、报表的内容和意义&#xff0c;以及如何制作进销存报表等方面…

opencv的cmake报错

opencv编译报错 CMakeDownloadLog.txt #use_cache "D:/opencv/.cache" #do_unpack "ippicv_2021.8_win_intel64_20230330_general.zip" "71e4f58de939f0348ec7fb58ffb17dbf" "https://raw.githubusercontent.com/opencv/opencv_3rdparty/1…

Ctags的安装和使用

ctags 是一个代码跟踪软件 由于在源码中&#xff0c;具有海量的代码&#xff0c;如果我们在源码中找特定的代码&#xff0c;需要大量时间&#xff0c;但是ctags则可以快速寻找 安装&#xff1a; sudo apt-get install ctagsctags使用 ctrl] //代码跟踪 crlT //代码返回我们…