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

自学TypeScript-基础、编译、类型

自学TypeScript-基础、编译、类型

  • TS 编译为 JS
  • 类型支持
    • 类型注解
    • 基础类型
    • `typeof` 运算符
    • 高级类型
      • class 类
        • 构造函数和实例方法
        • 继承
        • 可见性
        • 只读
      • 类型兼容性
      • 交叉类型
      • 泛型
        • 泛型约束
        • 多个泛型
        • 泛型接口
        • 泛型类
        • 泛型工具
      • 索引签名类型
      • 映射类型
      • 索引查询(访问)类型
    • 类型声明文件

TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,支持 ECMAScript 6 标准。因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译,将其编译成纯 JavaScript。

TS 和 JS 相比,增加的功能包括:

  • 类型批注和编译时类型检查
  • 类型推断
  • 类型擦除
  • 接口
  • 枚举
  • Mixin
  • 泛型编程
  • 名字空间
  • 元组
  • Await

并且有些功能从 ECMA2015 反向移植过来:

  • 模块
  • lambda 函数的箭头语法
  • 可选参数以及默认参数

因为 TS 是 JS 的超集,所以这里只研究与 JS 差别的部分

TS 编译为 JS

通常我们使用 .ts 作为 TypeScript 代码文件的扩展名。可以使用 tsc 命令将此文件编译为 JS 代码。例如

// app.ts
var message:string = "Hello World" 
console.log(message)
tsc app.ts
// app.ts 编译为 app.js
var message = "Hello World";
console.log(message);

当然因为绝大多数新版本的浏览器对 ts 语法的支持,可以跳过编译为 js 的步骤。

类型支持

因为 JS 类型系统存在“先天缺陷”,JS 代码中绝大部分错误都是类型错误(Uncaught TypeError),增加了Bug的查找和修改时间,严重影响开发效率。TS 是静态类型的编程语言,可以在编译期发现错误,方便Bug的查找和修改。

TS 支持所有 JS 的类型,但是 JS 不会检查类型的变化,但是 TS 会检查。

类型注解

在 TS 中,使用类型注解来为变量添加类型约束。

let age: number = 18	// 声明变量为数值类型

TS 的原始类型约束关键字有:

  • number
  • string
  • boolean
  • null
  • undefined
  • symbol

基础类型

数组类型严格将并不是 TS 新增的类型,但是 TS 的对象约束会根据具体类型的不同进行细分,使得数组也可以自成一类。

  • 数组类型
let number: number[] = [1, 3, 5]
let strings: Array<string> = ['a', 'b', 'c']
  • 联合类型
// 如果不确定变量的具体类型,或变量可能使用多个类型,则声明为联合类型
let a: number | string = 'a'	// 可以声明为数值或字符串
let arr: number | string[] = ['a', 'b', 'c']	// 可以声明为数值或字符串数组
// 如果数组中类型不止一种,则这样注解
let arr: (number | string)[] = [1, 'a', 3, 'b']		// 数组的元素可以是数值或字符串
  • 类型别名(自定义类型)
    当同一复杂类型被多次使用时,可以通过类型别名,简化该类型的使用
type CustomArray = (number | string)[]
let arr1: CustomArray = [1, 'a', 3, 'b']
  • 函数类型(参数类型、返回值类型)
// 单独指定参数和返回值的类型
function add(num1: number, num2: number): number {return num1 + num2
}
const add = (num1: number, num2: number): number => {return num1 + num2
}
// 同时指定参数、返回值类型
const add: (num1: number, num2: number) => number = (num1, num2) => {return num1 + num2
}
// 函数没有返回值,则返回值类型为 void
function greet(name: string): void {console.log('Hello', name)
}
// 可选参数
function mySlice(start?: number, end?: number): void {console.log('起始索引:', start, '结束索引:', end)
}
  • 对象类型(即对对象的属性和方法进行类型约束)
let person: { name: string; age: number; sayHi(): void } = {name: 'jack',age: 19,sayHi() {}
}
// 对象的属性和方法也可以是可选的
let config: { url: string; method?: string } = {...}
  • 接口类型(当一个对象类型被多次使用时,一般会使用接口来描述对象的类型,达到复用的目的)
interface IPerson {name: stringage: numbersayHi(): void
}
let person: IPerson = {name: 'jack',age: 19,sayHi() {}
}
// 接口类型和别名的区别在于,接口只能为对象指定类型,别名能为任意类型指定别名
// 如果两个接口之间有相同的属性或方法,可以将公共属性或方法抽离出来,通过继承来实现复用
interface Point2D { x: number; y: number }
interface Point3D extends Point2D { z: number }	// 继承了 Point2D 接口
  • 元组类型(另一种类型的数组,确定了元素的个数,以及特定索引元素的类型)
let posision: [number, number] = [39.5427, 116.2317]
  • 类型推论(在未明确指出类型的地方,使用类型推论机制,即省略类型注解)
// 类型推论场景1:声明变量时初始化
let age = 18
// 决定函数返回值时
function add(num1: number, num2: number) { return num1 + num2 }
  • 类型断言
    因为 ts 是静态语言,在编译时对于一些较为宽泛的对象并不确定其具体的属性,会造成无法访问某些特殊属性的错误。所以需要使用类型断言指定具体类型。
// 当有一个标签 <a href="http://www.test.com/" id="link"></a>
const aLink = document.getElementById('link')
// 变量 aLink 的类型是 HTMLElement,该是一个宽泛(不具体)的类型
// 包含所有标签公共的属性和方法,例如 id 属性,而不包含特有的属性,例如 href
// 如要操作特有的属性或方法,要进行类型断言
const aLink = document.getElementById('link') as HTMLAnchorElement
// as 后的类型必须为之前对象的子类
const aLink = <HTMLAnchorElement>document.getElementById('link')
  • 字面量类型
    在 ts 中,常量因为其值不能被改变,所以其类型为特殊的定义类型,即字面量类型。字面量类型可以是任意的 JS 字面量。通常字面量类型用在表示一组明确的可选值列表中。
const str = 'Hello TS'		// const 声明的变量为字面量类型,即 'Hello TS' 类型,而非 string 类型
function changeDirection(direction: 'up' | 'down' | 'left' | 'right') {		// 指定类型更加清晰明确console.log(direction)
}
  • 枚举类型
    枚举类型的功能类似于字面量类型+联合类型的组合功能,也可以表示一组明确的可选值
// 定义一组命名常量为枚举类型,它描述一个值,该值为这些命名常量中的一个
enum Direction { Up, Down, Left, Right }function changeDirection(direction: Direction) {return direction
}
// 类似于对象,使用时可以使用 . 来访问枚举成员
changeDirection(Direction.Left)
// 枚举成员是有值的,默认为从数值 0 开始自增,即 Up, Down, Left, Right 值分别为 0, 1, 2, 3
// 如有需要,可以在定义时初始化枚举值,未明确定义初始值的以前一个初始值增加1
enum Direction { Up = 10, Down, Left, Right }	// 枚举值为 10, 11, 12, 13
// 也可以初始化每个枚举成员
enum Direction { Up = 10, Down = 16, Left = 22, Right = 32 }
// 枚举成员也可以定义为字符串枚举,字符串枚举的每个成员必须初始化值
enum Direction { Up = 'UP', Down = 'DOWN', Left = 'LEFT', Right = 'RIGHT' }
  • any 类型(TS 不推荐使用 any 类型,因为这会丢失 TS 的类型保护的优势)
    any 类型为任意类型,会放弃 TS 的类型约束。
// 显式的声明 any 类型
let obj: any = { x: 0 }
// 隐式的声明 any 类型
let obj 	// 不提供类型注解也不初始化赋值
function fun(param) {		// 声明参数时不提供类型注解console.log(param)
}

typeof 运算符

在 JS 中,可以使用 typeof 运算符查看数据的类型,TS 也可以使用该运算符,并用于类型注解中

let p = { x: 1, y: 2 }
function formatPoint(point: typeof p) {}

高级类型

class 类

TS 全面支持 ES2015 中引入的 class ,并添加了类型注解和其他语法(比如可见性修饰符)。class 的基础使用 TS 和 JS 相同

class Person {}
const p = new Person()

根据 ts 中的类型推论,Person 类的实例对象 p 的类型是 Person。ts 中的 class 不仅提供了 class 语法功能,也作为一种类型存在。

ts 声明类需要进行类型注解或添加默认初始值

class Person {age: numbergender = '男'		// 类型推论
}

构造函数和实例方法

类的构造函数需要指定类型注解,否则会被隐式推断为 any。构造函数不需要返回值类型

class Person {age: numbergender: stringconstructor(age: number, gender: string) {this.age = agethis.gender = gender}
}

类的实例方法的类型注解(参数和返回值)与函数用法相同

class Point {x = 10y = 10scale(n: number): void {this.x *= nthis.y *= n}
}

继承

js 提供了类的继承 extends 可以继承父类,而 ts 提供另一种继承方法: implements,实现接口

// extends 继承父类
class Animal {move() { console.log('animal move') }
}
class Dog extends Animal {		// 继承父类bark() { console.log('wang!') }
}
const dog = new Dog()
// implements 实现接口
interface Singable {sing(): void
}
class Person implements Singable {		// 类中必须提供接口中所有方法和属性sing() {console.log('唱歌')}
}

ts 中接口class 类的区别在于,接口是对象的属性和方法的描述,是一种类型、约束。而类是对象的模板,类可以实例化为对象。

可见性

可以使用可见性修饰符来控制 class 的方法或属性对于 class 外的代码是否可见。可见性修饰符包括:

  • public(公有)
    公有的成员可以被任何地方访问,是默认的可见性
class Animal {public move() {console.log('Moving!')}
}
  • protected(受保护)
    受保护的成员仅对其声明所在类和子类中(非实例对象)可见
class Animal {protected move() { console.log('Moving!') }
}
class Dog extends Animal {bark() {console.log('wang!')this.move()		// 可以访问父类的 protected 方法}
}
  • private(私有)
    私有的成员仅对当前类可见,对实例对象以及子类都是不可见的
class Animal {private move() { console.log('Moving!') }walk() {this.move()}
}

只读

class 类常用的修饰符还有 readonly 修饰符,用来防止在构造函数之外对属性进行赋值

class Person {readonly age: number = 18constructor(age: number) {this.age = age}
}

类型兼容性

类型兼容性并不是一个具体的类型,而是 ts 中类型的一个特性。

现在常用的两种类型系统为

  • Structural Type System 结构化类型系统
  • Nominal Type System 标明类型系统

TS 采用的是结构化类型系统,也叫 duck typing(鸭子类型),类型检查关注的是值所具有的形状。也就是说,在结构类型系统中,如果两个对象具有相同的形状,则认为它们属于同一类型。

class Point { x: number; y: number }
class Point2D { x: number; y: number }
const p: Point = new Point2D()			// 类型注解为 Point 类型,但是由于类型兼容性,可以使用 Point2D 类进行实例化

因为 TS 是结构化类型系统,只检查 Point 和 Point2D 的结构是否相同。如果使用标明类型系统,如 C#, Java 等,因为是不同的类,类型无法兼容。

在实际使用的对象类型中,如果 y 的成员至少与 x 相同,则 x 兼容 y (成员多的可以赋值给少的),例如

class Point { x: number; y: number }
class Point3D { x: number; y: number; z: number }
const p: Point = new Point3D()

除了 class 之外,TS 的其他类型也存在相互兼容的情况:

  • 接口之间的兼容性类似于 class,且 class 和 interface 之间也可以兼容
  • 函数之间也有类型兼容性,不过较为赋值,需要考虑参数个数、参数类型、返回值类型
// 参数个数的影响:参数多的兼容参数少的(参数少的可以赋值给多的)
type F1 = (a: number) => void
type F2 = (a: number, b: number) => void
let f1: F1
let f2: F2 = f1
// 最常用的是数组的 forEach 方法,此方法的函数参数应该有3个参数,但实际使用中经常只使用第一个参数
// 即省略用不到的函数参数
arr.forEach(item => {})
arr.forEach((value, index, array) => {})
// 参数类型的影响:相同位置的参数类型要相同(原始类型)或兼容(对象类型)
type F1 = (a: number) => string
type F2 = (a: number) => string
let f1: F1
let f2: F2 = f1
// 如果函数参数是接口或 class,则和之前的接口或对象兼容性冲突
interface Point2D { x: number; y: number }
interface Point3D { x: number: y: number; z: number }
type F2 = (p: Point2D) => void
type F3 = (p: Point3D) => void
let f2: F2
let f3: F3 = f2		// f2 的成员少,则可以赋值给成员多的 f3,不可以反过来
// 返回值类型的影响:只关注返回值类型本身
// 返回值类型是原始类型,可以互相兼容
type F5 = () => string
type F6 = () => string
let f5: F5
let f6: F6 = f5		
// 返回值类型是对象或接口,成员多的可以赋值给成员少的
type F7 = () => { name: string }
type F8 = () => { name: string; age: number }
let f7: F7
let f8: F8
f7 = f8

交叉类型

交叉类型(&)功能类似于接口继承(extends),用于组合多个类型为一个类型(常用于对象类型)

interface Person { name: string }
interface Contact { phone: string }
type PersonDetail = Person & Contact	// PersonDetail 同时具备了 Person 和 Contact 的所有属性类型

&extends 的不同在于,同名属性之间,处理类型冲突的方式不同

interface A {fn: (value: number) => string
}
interface B extends A {fn: (value: string) => string	// 会报错,因为 extends 检查到类型不兼容
}
interface C {fn: (value: string) => string
}
type D = A & C		// 不会报错,交叉类型兼容两者,相当于 fn: (value: string | number) => string

泛型

泛型是在保证类型安全的前提下,让函数等与多种类型一起工作,从而实现复用,常用于函数、接口、class 中。例如:

// 函数返回参数数据本身,可以接收任意类型。如果不使用 any 类型,普通的类型只能实现单一类型,而使用泛型则可以实现
// 在函数名称后使用 <> 尖括号,并添加类型变量 Type。它是一种特殊类型的变量,它处理类型而不是值
function id<Type>(value: Type): Type { return value }
// 调用时再指定 Type 的具体类型
const num = id<number>(10)
const str = id<string>('a')
// 在实际使用中,通常会省略尖括号达到简化使用
const num1 = id(10)
const str1 = id('a')

泛型约束

因为默认情况下,泛型函数的变量类型 Type 可以代表多个类型,这导致无法访问任何属性,例如

function id<Type>(value: Type): Type {console.log(value.length)		// 会报错,因为类型 Type 不一定有 length 属性return value
}

此时可以添加泛型约束来收缩类型范围。泛型约束主要有两种方式:1.指定更加具体的类型,2.添加约束

// 指定更加具体的类型,收缩至数组类型
function id<Type>(value: Type[]): Type[] {console.log(value.length)return value
}
// 添加约束,满足某些条件要求
interface ILength { length: number }
function id<Type extends ILenght>(value Type): Type {console.log(value.length)return value
}

多个泛型

泛型的类型变量可以有多个,且类型变量之间也可以进行约束。例如

// 设置两个泛型,第二个泛型受到第一个泛型约束
function getProp<Type, Key extends keyof Type>(obj: Type, key: key) {return obj[key]
}

泛型接口

接口也可以使用泛型,不过在使用时,需要显式指定具体类型。

interface IdFunc<Type> {id: (value: Type) => Typeids: () => Type[]
}
let obj: IdFunc<number> = {id(value) { return value },ids() { return [1, 3, 5] }
}

实际上, JS 中的数组在 TS 中就是一个泛型接口

const strs = ['a', 'b', 'c']
const nums = [1, 2, 3]
// forEach 方法的参数就是根据数组元素不同而不同

泛型类

class 也可以使用泛型,例如 React 的组件的基类就是泛型类,不同的组件会有不同的成员类

interface IState { count: number }
interface IProps { maxLength: number }
class InputCount extends React.Component<IProps, IState> {state: IState = { count: 0 }render() { return <div>{this.props.maxLength}</div> }
}

创建泛型类类似于创建泛型接口

class GenericNumber<NumType> {defaultValue: NumTypeadd: (x: NumType, y: NumType) => NumType
}
const myNum = new GenericNumber<number>()
myNum.defaultValue = 10

泛型工具

TS 内置了一些常用的工具类型,来简化 TS 中的一些常见操作,最常用的有以下几种:

  • Partial<Type> 用来构建一个类型,将 Type 的所有属性设置为可选
interface Props {id: stringchildren: number[]
}
type PartialProps = Partial<Props>		// Props 的属性是必选的,经过 Partial 处理,新类型所有属性为可选
  • Readonly<Type> 用来构建一个类型,将 Type 的所有属性设置为只读
  • Pick<Type, Keys> 可以从Type中选择一组属性来构造新类型
interface Props {id: stringtitle: stringchildren: number[]
}
type PickProps = Pick<Props, 'id' | 'title'>
  • Record<Keys, Type> 用来构造一个对象类型,属性键为Keys,属性类型为Type,注意所有属性类型是相同的
// 创建一个对象,属性键为 a, b, c 类型均为 string[]
type RecordObj = Record<'a' | 'b' | 'c', string[]>
// 等同于
type RecordObj = {a: string[];b: string[];c: string[];
}

索引签名类型

绝大多数情况下,在使用对象前就能确定对象的结构,并为对象添加准确的类型。但是偶尔无法确定对象中有哪些属性(或者说对象中可以出现任意多个属性),此时可以使用索引签名类型

interface AnyObj {[key: string]: number
}

该例中使用 [key: string] 来约束该接口中允许出现的属性名称类型,这样可以出现任意多个符合约束的属性。 key 只是一个占位符,可以换成任意合法变量名称。例如 JS 中,对象 {} 的键是 string 类型的。

映射类型

映射类型可以基于旧类型创建新类型(对象类型),减少重复,提升开发效率。例如之前的泛型类型在内部是由映射类型实现的。

// 根据联合类型创建
type PropKeys = 'x' | 'y' | 'z'
type Type1 = { x: number; y: number; z: number}
// 使用映射类型实现:
type Type2 = { [key in PropKeys]: number }
// 根据对象类型创建
type Props = { a: number; b: string; c: boolean }
type Type3 = { [key in keyof Props]: number }
// 泛型工具类型 Partial<Type> 的实现
type Partial<Type> = {[P in keyof Type]?: T[P]
}

映射类型是基于索引签名类型的,所以该语法类似于索引签名类型,也使用 []。需注意的是,映射类型只能在类型别名中使用,不能在接口中使用。

索引查询(访问)类型

Partial<Type> 的实现中, T[P] 的语法在 TS 中叫做索引查询(访问)类型,可以用来查询属性的类型

type Props = { a: number; b: string; c: boolean }
type TypeA = Props['a']		// 即 number
type TypeB = Props['a' | 'b']	// number | string
type TypeC = Props[keyof Props]		// number | string | boolean

类型声明文件

TS 需要编译成 JS 代码执行,TS 提供了类型保护机制,为了将此机制延续到 JS,可以使用类型声明文件来为 JS 提供类型信息。

TS 中有两种文件类型,ts 文件和 d.ts 文件。ts 文件就是 ts 的可执行代码文件, d.ts 文件即类型声明文件,只做类型声明使用。

使用类型声明文件,在 d.ts 文件中使用 export 导出(也可以使用import/export实现模块化功能)。在需要使用共享类型的 ts 文件中,通过 import 导入即可(导入时 .d.ts 后缀可以省略)

// index.d.ts
type Props = { x: number; y: number }export { Props }
// a.ts
import { Props } from './index'let p1: Props = { x: 1, y:2 }

相关文章:

自学TypeScript-基础、编译、类型

自学TypeScript-基础、编译、类型 TS 编译为 JS类型支持类型注解基础类型typeof 运算符高级类型class 类构造函数和实例方法继承可见性只读 类型兼容性交叉类型泛型泛型约束多个泛型泛型接口泛型类泛型工具 索引签名类型映射类型索引查询(访问)类型 类型声明文件 TypeScript 是…...

nginx配置https

1.安装nginx 安装完成后检查 nginx -V2.申请证书与上传 阿里云申请免费的证书 然后上传到某个目录 3.修改nginx配置 #user nobody; worker_processes 1;#error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;#pid …...

windows Etcd的安装与使用

一、简介 etcd是一个分布式一致性键值存储&#xff0c;其主要用于分布式系统的共享配置和服务发现。 etcd由Go语言编写 二、下载并安装 1.下载地址&#xff1a; https://github.com/coreos/etcd/releases 解压后的目录如下&#xff1a;其中etcd.exe是服务端&#xff0c;e…...

【py】为什么用 import tkinter 不能运行

为什么用 import tkinter 不能运行 ━━━━━━━━━━━━━━━━━━━━━━ 要显示一个信息框&#xff0c;为什么用 import tkinter 不能运行&#xff0c;改成from tkinter import messagebox 就可以运行了&#xff1f; 可能是因为您的代码中只使用了 messagebox 这个模…...

【深度学习】实验04 交叉验证

文章目录 交叉验证划分自定义划分K折交叉验证留一交叉验证留p交叉验证随机排列交叉验证分层K折交叉验证分层随机交叉验证 分割组 k-fold分割留一组分割留 P 组分割随机分割时间序列分割 交叉验证 # 导入相关库# 交叉验证所需函数 from sklearn.model_selection import train_t…...

whisper语音识别部署及WER评价

1.whisper部署 详细过程可以参照&#xff1a;&#x1f3e0; 创建项目文件夹 mkdir whisper cd whisper conda创建虚拟环境 conda create -n py310 python3.10 -c conda-forge -y 安装pytorch pip install --pre torch torchvision torchaudio --extra-index-url 下载whisper p…...

java太卷了,怎么办?

忧虑&#xff1a; 马上就到30岁了&#xff0c;最近对于自己职业生涯的规划甚是焦虑。在网站论坛上&#xff0c;可谓是哀鸿遍野&#xff0c;大家纷纷叙述着自己被裁后求职的艰辛路程&#xff0c;这更加加深了我的忧虑&#xff0c;于是在各大论坛开始“求医问药”&#xff0c;想…...

android多屏触摸相关的详解方案-安卓framework开发手机车载车机系统开发课程

背景 直播免费视频课程地址&#xff1a;https://www.bilibili.com/video/BV1hN4y1R7t2/ 在做双屏相关需求开发过程中&#xff0c;经常会有对两个屏幕都要求可以正确触摸的场景。但是目前我们模拟器默认创建的双屏其实是没有办法进行触摸的 修改方案1 静态修改方案 使用命令…...

微信小程序 实时日志

目录 实时日志 背景 如何使用 如何查看日志 注意事项 实时日志 背景 为帮助小程序开发者快捷地排查小程序漏洞、定位问题&#xff0c;我们推出了实时日志功能。从基础库2.7.1开始&#xff0c;开发者可通过提供的接口打印日志&#xff0c;日志汇聚并实时上报到小程序后台…...

Spring AOP基于注解方式实现和细节

目录 一、Spring AOP底层技术 二、初步实现AOP编程 三、获取切点详细信息 四、 切点表达式语法 五、重用&#xff08;提取&#xff09;切点表达式 一、Spring AOP底层技术 SpringAop的核心在于动态代理&#xff0c;那么在SpringAop的底层的技术是依靠了什么技术呢&#x…...

CVPR2023论文及代码合集来啦~

以下内容由马拉AI整理汇总。 下载&#xff1a;点我跳转。 狂肝200小时的良心制作&#xff0c;529篇最新CVPR2023论文及其Code&#xff0c;汇总成册&#xff0c;制作成《CVPR 2023论文代码检索目录》&#xff0c;包括以下方向&#xff1a; 1、2D目标检测 2、视频目标检测 3、…...

基于ETLCloud的自定义规则调用第三方jar包实现繁体中文转为简体中文

背景 前面曾体验过通过零代码、可视化、拖拉拽的方式快速完成了从 MySQL 到 ClickHouse 的数据迁移&#xff0c;但是在实际生产环境&#xff0c;我们在迁移到目标库之前还需要做一些过滤和转换工作&#xff1b;比如&#xff0c;在诗词数据迁移后&#xff0c;发现原来 MySQL 中…...

TDesign在按钮上加入图标组件

在实际开发中 我们经常会遇到例如 添加或者查询 我们需要在按钮上加入图标的操作 TDesign自然也有预备这样的操作 首先我们打开文档看到图标 例如 我们先用某些图标 就可以点开下面的代码 可以看到 我们的图标大部分都是直接用tdesign-icons-vue 导入他的组件就可以了 而我…...

Linux 终端命令行 产品介绍

Linux命令手册内置570多个Linux 命令&#xff0c;内容包含 Linux 命令手册。 【软件功能】&#xff1a; 文件传输 bye、ftp、ftpcount、ftpshut、ftpwho、ncftp、tftp、uucico、uucp、uupick、uuto、scp备份压缩 ar、bunzip2、bzip2、bzip2recover、compress、cpio、dump、gun…...

计算机毕设 基于深度学习的植物识别算法 - cnn opencv python

文章目录 0 前言1 课题背景2 具体实现3 数据收集和处理3 MobileNetV2网络4 损失函数softmax 交叉熵4.1 softmax函数4.2 交叉熵损失函数 5 优化器SGD6 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&a…...

【STM32】学习笔记-江科大

【STM32】学习笔记-江科大 1、STM32F103C8T6的GPIO口输出 2、GPIO口输出 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口可配置为8种输入输出模式引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V输出模式下可控制端口输出高低电平&#…...

Doris架构中包含哪些技术?

Doris主要整合了Google Mesa(数据模型)&#xff0c;Apache Impala(MPP Query Engine)和Apache ORCFile (存储格式&#xff0c;编码和压缩)的技术。 为什么要将这三种技术整合? Mesa可以满足我们许多存储需求的需求&#xff0c;但是Mesa本身不提供SQL查询引擎。 Impala是一个…...

《vue3实战》通过indexOf方法实现电影评价系统的模糊查询功能

目录 前言 一、indexOf是什么&#xff1f;indexOf有什么作用&#xff1f; 含义&#xff1a; 作用&#xff1a; 二、功能实现 这段是查询过程中过滤筛选功能的代码部分: 分析&#xff1a; 这段是查询用户和性别功能的代码部分&#xff1a; 分析&#xff1a; 三、最终效…...

java对时间序列每x秒进行分组

问题&#xff1a;将一个时间序列每5秒分一组&#xff0c;返回嵌套的list&#xff1b; 原理&#xff1a;int除int会得到一个int&#xff08;也就是损失精度&#xff09; 输入&#xff1a;排序后的list&#xff0c;每几秒分组值 private static List<List<Long>> get…...

八月更新 | CI 构建计划触发机制升级、制品扫描 SBOM 分析功能上线!

点击链接了解详情 这个八月&#xff0c;腾讯云 CODING DevOps 对持续集成、制品管理、项目协同、平台权限等多个产品模块进行了升级改进&#xff0c;为用户提供更灵活便捷的使用体验。以下是 CODING 新功能速递&#xff0c;快来看看是否有您期待已久的功能特性&#xff1a; 01…...

Spring核心配置步骤-完全基于XML的配置

Spring框架的核心配置涉及多个方面&#xff0c;包括依赖注入&#xff08;DI&#xff09;、面向切面编程&#xff08;AOP&#xff09;等。以下是一般情况下配置Spring应用程序的核心步骤&#xff1a; 1. **引入Spring依赖&#xff1a;** 在项目的构建工具&#xff08;如Maven、…...

宏基官网下载的驱动怎么安装(宏基笔记本如何安装系统)

本文为大家介绍宏基官网下载的驱动怎么安装宏基笔记本驱动(宏基笔记本如何安装系统)&#xff0c;下面和小编一起看看详细内容吧。 宏碁笔记本怎么一键更新驱动 1. 单击“开始”&#xff0c;然后选择“所有程序”。 2. 单击Acer&#xff0c;然后单击Acer eRecovery Management。…...

基于AVR128单片机抢答器proteus仿真设计

一、系统方案 二、硬件设计 原理图如下&#xff1a; 三、单片机软件设计 1、首先是系统初始化 void timer0_init() //定时器初始化 { TCCR00x07; //普通模式&#xff0c;OC0不输出&#xff0c;1024分频 TCNT0f_count; //初值&#xff0c;定时为10ms TIFR0x01; //清中断标志…...

openGauss学习笔记-54 openGauss 高级特性-MOT

文章目录 openGauss学习笔记-54 openGauss 高级特性-MOT54.1 MOT特性及价值54.2 MOT关键技术54.3 MOT应用场景54.4 不支持的数据类型54.5 使用MOT54.6 将磁盘表转换为MOT openGauss学习笔记-54 openGauss 高级特性-MOT openGauss引入了MOT&#xff08;Memory-Optimized Table&…...

InsCode AI 创作助手

RESTful API是一种架构风格和设计原则&#xff0c;用于构建Web服务和应用程序。它基于HTTP协议&#xff0c;以资源为中心&#xff0c;对资源进行各种操作。RESTful API的主要特点包括&#xff1a; 使用HTTP协议进行传输和通信&#xff1b;操作和状态均以资源为中心&#xff1b…...

java对时间序列根据阈值进行连续性分片

问题描述&#xff1a;我需要对一个连续的时间戳list进行分片&#xff0c;分片规则是下一个数据比当前数据要大于某一个阈值则进行分片&#xff1b; 解决方式&#xff1a; 1、输入的有顺序的list &#xff0c;和需要进行分片的阈值 2、调用方法&#xff0c;填入该排序的list和阈…...

Pillow:Python的图像处理库(安装与使用教程)

在Python中&#xff0c;Pillow库是一个非常强大的图像处理库。它提供了广泛的图像处理功能&#xff0c;让我们可以轻松地操作图像&#xff0c;实现图像的转换、裁剪、缩放、旋转等操作。此外&#xff0c;Pillow还支持多种图像格式的读取和保存&#xff0c;包括JPEG、PNG、BMP、…...

自然语言处理-NLP

目录 自然语言处理-NLP 致命密码&#xff1a;一场关于语言的较量 自然语言处理的发展历程 兴起时期 符号主义时期 连接主义时期 深度学习时期 自然语言处理技术面临的挑战 语言学角度 同义词问题 情感倾向问题 歧义性问题 对话/篇章等长文本处理问题 探索自然语言…...

柠檬水找零【贪心算法-】

柠檬水找零 在柠檬水摊上&#xff0c;每一杯柠檬水的售价为 5 美元。顾客排队购买你的产品&#xff0c;&#xff08;按账单 bills 支付的顺序&#xff09;一次购买一杯。 每位顾客只买一杯柠檬水&#xff0c;然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零&…...

el-date-picker设置开始时间小于结束时间

一. date-picker Template <template><el-form-item label"开始时间" prop"startDate"><el-date-pickerv-model.trim"form.startDate"type"datetime"placeholder"请选择日期"value-format"yyyy-MM-dd …...

Linux内核学习(十三)—— 设备与模块(基于Linux 2.6内核)

目录 一、设备类型 二、模块 构建模块 安装模块 载入模块 一、设备类型 在 Linux 以及 Unix 系统中&#xff0c;设备被分为以下三种类型&#xff1a; 块设备&#xff08;blkdev&#xff09;&#xff1a;以块为寻址单位&#xff0c;块的大小随设备的不同而变化&#xff1…...

计算机视觉工程师学习路线

1. 学习编程语言和基础库 学习Python语言,掌握基础语法、函数、面向对象编程等概念学习Numpy库,用于科学计算和多维数组学习OpenCV库,包含了许多图像处理和计算机视觉算法学习TensorFlow/PyTorch,主要的深度学习框架 2. 学习数字图像处理算法 图像的表示方式(像素、灰度、二…...

c#多线程—基础概念到“双色球”项目实现(附知识点目录、代码、视频)

总结&#xff1a;视频中对于多线程讲的非常透彻&#xff0c;从线程基础概念—>.net不同版本出现的线程方法—>多线程常出现问题—>双色球项目实践&#xff0c;每个知识点都有代码实操&#xff0c;受益匪浅。附上学习笔记和实操代码。 视频 目录 一、线程、进程概念及优…...

【OpenCV入门】第一部分——图像处理基础

本文结构 图像处理的基本操作读取图像imread() 显示图像imshow()waitKey()destroyAllWindows() 保存图像imwrite() 获取图像属性 像素确定像素的位置获取像素的BGR值修改像素的BGR值 色彩空间GRAY色彩空间cvtColor()——从BGR色彩空间转换到GRAY色彩空间 HSV色彩空间从BGR色彩空…...

vue3+ts+tinynce富文本编辑器+htmlDocx+file-saver 配合实现word下载

vue3 请下载html-docx-js-typescript&#xff0c;否则会报错类型问题 //报告导出word import * as htmlDocx from "html-docx-js-typescript";//ts-ignore import { saveAs } from file-saver// 下载文件&#xff0c; const downloadFile (row)> {try {const co…...

论文阅读 The Power of Tiling for Small Object Detection

The Power of Tiling for Small Object Detection Abstract 基于深度神经网络的技术在目标检测和分类方面表现出色。但这些网络在适应移动平台时可能会降低准确性&#xff0c;因为图像分辨率的增加使问题变得更加困难。在低功耗移动设备上实现实时小物体检测一直是监控应用的…...

【FreeRTOS】【应用篇】消息队列【下篇】

前言 本篇文章主要对 FreeRTOS 中消息队列的概念和相关函数进行了详解消息队列【下篇】详细剖析了消息队列中发送、接收时队列消息控制块中各种指针的行为&#xff0c;以及几个发送消息和接收消息的函数的运作流程笔者有关于 【FreeRTOS】【应用篇】消息队列【上篇】——队列基…...

芯片技术的崭新时代:探索未来的可能性

引言 芯片作为现代科技领域的核心&#xff0c;扮演着无可替代的角色。从智能手机到数据中心&#xff0c;从医疗设备到智能家居&#xff0c;芯片技术已经深刻地改变了我们的生活。然而&#xff0c;随着技术的不断发展&#xff0c;芯片行业也在经历着一场前所未有的变革。本文将…...

博流RISC-V芯片Eclipse环境搭建

文章目录 1、下载 Eclipse2、导入 bouffalo_sdk3、编译4、烧录5、使用ninja编译 之前编译是通过 VSCode 编译&#xff0c;通过手工输入 make 命令编译&#xff0c;我们也可以通过 Eclipse 可视化 IDE 来编译、烧录。 1、下载 Eclipse 至 Eclipse 官网 https://www.eclipse.org…...

智慧水产养殖方案,守护养殖水产品安全!

水产品在人们的饮食文化中占据着举足轻重的地位&#xff0c;更是人们摄入蛋白质的重要来源。因此&#xff0c;保障食品安全&#xff0c;提升养殖水产品的品质至关重要然。而传统的人工观察水产养殖方式较为单一&#xff0c;难以及时发现水质问题和投喂情况&#xff0c;容易导致…...

前端vue引入高德地图入门教程

距离上一篇关于前端项目中使用高德地图的文章已经将近5年之久&#xff0c; 这是我的第一篇关于高德地图的文章 这期间前端技术日新月异&#xff0c;5年前JQuery还如日中天&#xff0c;如今已经销声匿迹&#xff0c;很少有公司招聘还在要求JQuery&#xff0c;更多的是Vue、React…...

【LeetCode题目详解】第八章 贪心算法 part05 435. 无重叠区间 763.划分字母区间 56. 合并区间 (day36补)

本文章代码以c为例&#xff01; 一、力扣第435题&#xff1a;无重叠区间 题目&#xff1a; 给定一个区间的集合 intervals &#xff0c;其中 intervals[i] [starti, endi] 。返回 需要移除区间的最小数量&#xff0c;使剩余区间互不重叠 。 示例 1: 输入: intervals [[1,…...

数据的语言:学习数据可视化的实际应用

数据可视化应该学什么&#xff1f;这是一个在信息时代越来越重要的问题。随着数据不断增长和积累&#xff0c;从社交媒体到企业业务&#xff0c;从科学研究到医疗健康&#xff0c;我们都面临着海量的数据。然而&#xff0c;数据本身往往是冰冷、抽象的数字&#xff0c;对于大多…...

【Flutter】Flutter简介

Flutter是Google开发的一款用于构建高性能、高保真移动应用程序的开源UI工具包。它允许开发人员使用Dart语言来构建跨平台的移动应用程序&#xff0c;并提供了丰富的UI组件、动画效果和手势识别等功能。 以下是Flutter入门的一些详细介绍&#xff1a; Flutter概述 Flutter是一…...

做区块链卡牌游戏有什么好处?

区块链卡牌游戏是一种基于区块链技术的创新性游戏形式&#xff0c;它将传统的卡牌游戏与区块链技术相结合&#xff0c;实现了去中心化、数字化资产的交易和收集。这种新型游戏形式正逐渐在游戏行业引起了广泛的关注和热潮。本文将深入探讨区块链卡牌游戏的定义、特点以及其在未…...

C语言每日一练------Day(5)

本专栏为c语言练习专栏&#xff0c;适合刚刚学完c语言的初学者。本专栏每天会不定时更新&#xff0c;通过每天练习&#xff0c;进一步对c语言的重难点知识进行更深入的学习。 今日练习题关键字&#xff1a;错误的集合 密码检查 &#x1f493;博主csdn个人主页&#xff1a;小小u…...

(Windows )本地连接远程服务器(Linux),免密码登录设置

在使用VScode连接远程服务器时&#xff0c;每次打开都要输入密码&#xff0c;以及使用ssh登录或其它方法登录&#xff0c;都要本地输入密码&#xff0c;这大大降低了使用感受&#xff0c;下面总结了免密码登录的方法&#xff0c;用起来巴适得很&#xff0c;起飞。 目录 PowerSh…...

Python 面试:异常处理机制

格式&#xff1a; 继承Exception实现自定义异常。 注意&#xff1a;这里是继承Exception类&#xff0c;而不是BaseException类&#xff0c;因为继承BaseException可能会导致捕获不到自定义异常。 class MyException(Exception):passtry:raise MyException(my salary is too…...

Matlab图像处理-水平镜像

镜像变换 镜像变换又常称为对称变换&#xff0c;它可以分为水平对称、垂直对称等多种变换。对称变换后&#xff0c;图像的宽和高不变。 图像的镜像分为两种垂直镜像和水平镜像。 水平镜像即将图像左半部分和右半部分以图像竖直中轴线为中心轴进行对换&#xff1b; 竖直镜像…...

Ansys Zemax | 手机镜头设计 - 第 2 部分:使用 OpticsBuilder 实现光机械封装

本文是3篇系列文章的一部分&#xff0c;该系列文章将讨论智能手机镜头模块设计的挑战&#xff0c;从概念、设计到制造和结构变形的分析。本文是三部分系列的第二部分。概括介绍了如何在 CAD 中编辑光学系统的光学元件以及如何在添加机械元件后使用 Zemax OpticsBuilder 分析系统…...