【鸿蒙 HarmonyOS 4.0】TypeScript开发语言
一、背景
HarmonyOS 应用的主要开发语言是 ArkTS,它由 TypeScript(简称TS)扩展而来,在继承TypeScript语法的基础上进行了一系列优化,使开发者能够以更简洁、更自然的方式开发应用。值得注意的是,TypeScript 本身也是由另一门语言 JavaScript 扩展而来。因此三者的关系如下图所示
二、TypeScript
2.1、运行环境
2.1.1、线上Playground
TypeScript提供了一个线上的 Playground 供练习使用,地址为TypeScript: 演练场 - 一个用于 TypeScript 和 JavaScript 的在线编辑器。
2.1.2、本地运行环境
2.1.2.1、采用的是VSCode 编辑器
2.1.2.2、前提条件
1、安装插件:Code Runner:它提供了简便的代码执行功能,支持多种编程语言,使开发者能够快速运行和调试代码片段。
2、安装Node.js并配置Path
环境变量
说明:我已经安装了Node.js,便不重复安装了
为了方便在终端执行Node.js相关的命令,我们需要将Node.js的安装目录加入到Path
环境变量下
步骤1:首先在DevEco Studio的设置界面查看Node.js的安装目录
步骤2:然后打开环境变量配置面板,按下 Win
+R
,唤起运行窗口,之后运行命令 sysdm.cpl
步骤3:点击高级选项卡,并点击环境变量
步骤4:在系统变量中选中 Path
,并点击编辑
步骤5:点击新建,并填入Node.js的安装目录,完成后点击确定
3、安装ts-node
这是一个 TypeScript 的运行环境,它允许我们直接运行 TypeScript 代码。ts-node的安装和运行依赖于Node.js环境,已经安装了Node.js
npm install -g ts-node
在终端中输入node -v 和ts-node -v后出现各自版本,说明这两个已经安装成功了,如下:
注:完成后需要重新启动VSCode,另其重新加载环境变量和相关依赖。
2.1.2.3、编写程序并运行
首先在合适的位置创建一个工程目录,例如C:\Users\......\hello-ts
,然后使用VSCode打开目录,创建ts文件,并编写Typescript代码运行
问题:运行ts时出现以下错误,百度后发现是由于 ts-node 版本升级导致的兼容性问题
解决:需要在项目中安装 @types/node
npm install --save-dev @types/node
效果: 安装 @types/node 后,再运行就能够正常打印日志了
2.2、声明
2.2.1、变量声明
2.2.2、常量声明
let
用于声明变量,而const
用于声明常量,两者的区别是变量在赋值后可以修改,而常量在赋值后便不能再修改。
const b:number = 200;
2.2.3、类型推断
如果一个变量或常量的声明包含了初始值,TS 便可以根据初始值进行类型推断,此时我们就可以不显式指定其类型,例如
let c = 60;
console.log(typeof c); //number
2.3、常用数据类型
2.3.1、number
number
表示数字,包括整数和浮点数,例如: 100
、-33
、2.5
、-3.9
let a :number = 100
let b :number = -33
let c :number = 2.5
let d :number = -3.9
2.3.2、string
string
表示字符串,例如: 你好
、hello
let a:string = '你好'
let b:string = 'hello'
2.3.3、boolean
boolean
表示布尔值,可选值为:true
、false
let isOpen:boolean = true
let isDone:boolean = false
2.3.4、数组
数组类型定义由两部分组成,元素类型[]
,例如number[]
表示数字数组,string[]
表示字符串数组,数组类型的变量可由数组字面量——[item1,item2,item3]
进行初始化。
let a: number[] = []
let b: string[] = ['你好', 'hello']
2.3.5、对象
在TS中,对象(object)是一种一系列由属性名称和属性值组成的数据结构,例如姓名:'张三', 年龄:10, 性别:'男'
。对象类型的声明需要包含所有属性的名称及类型,例如{name: string, age: number, gender: string}
,对象类型的变量可以通过对象字面量——{name:'张三', age:10, gender:'男'}
进行初始化。
let person: {name:string, age:number, gender:string} = {name:'张三', age:10, gender:'男'};
2.4、函数
2.4.1、函数声明语法
声明函数的基础语法如下
2.4.2、参数
2.4.2.1、特殊语法
①可选参数
可选参数通过参数名后的?
进行标识,如以下案例中的gender?
参数。
function getPersonInfo(name: string, age: number, gender?: string): string {if (gender === undefined) {gender = '未知'}return `name:${name},age:${age},gender:${gender}`;
}let p1 = getPersonInfo('zhagnsan', 10, '男')
let p2 = getPersonInfo('lisi', 15);
console.log(p1);
console.log(p2);
注:调用函数时,未传递可选参数,则该参数的值为undefined
。
②默认参数
可在函数的参数列表为参数指定默认值,如以下案例中的gender: string='未知'
参数。
function getPersonInfo(name: string, age: number, gender: string='未知'): string {return `name:${name},age:${age},gender:${gender}`;
}let p1 = getPersonInfo('zhagnsan', 10, '男')
let p2 = getPersonInfo('lisi', 15);
console.log(p1);
console.log(p2);
2.4.2.2、 特殊类型
①联合类型
一个函数可能用于处理不同类型的值,这种情况可以使用联合类型,例如以下案例中的message: number | string
function printNumberOrString(message: number | string) {console.log(message)
}printNumberOrString('a')
printNumberOrString(1)
②任意类型
若函数需要处理任意类型的值,则可以使用any
类型,例如以下案例中的message: any
function print(message:any) {console.log(message)
}print('a')
print(1)
print(true)
2.4.3、 返回值
2.4.3.1、特殊类型
若函数没有返回值,则可以使用void
作为返回值类型,其含义为空。
function test(): void {console.log('hello');
}
2.4.3.2、类型推断
函数的返回值类型可根据函数内容推断出来,因此可以省略不写。
function test() {console.log('hello');
}function sum(a: number, b: number) {return a + b;
}
2.4.4、函数声明特殊语法
①匿名函数
匿名函数的语法结构简洁,特别适用于简单且仅需一次性使用的场景。
let numbers: number[] = [1, 2, 3, 4, 5]
numbers.forEach(function (number) {console.log(number);
})
注意:匿名函数能够根据上下文推断出参数类型,因此参数类型可以省略。
②箭头函数
匿名函数的语法还可以进一步的简化,只保留参数列表和函数体两个核心部分,两者用=>
符号连接。
let numbers: number[] = [1, 2, 3, 4, 5]
numbers.forEach((num) => { console.log(num) })
2.5、类
2.5.1、类介绍
类(class)是面向对象编程语言中的一个重要概念。
面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,其核心理念在于将程序中的数据与操作数据的方法有机地组织成对象,从而使程序结构更加模块化和易于理解。通过对象之间的协同合作,实现更为复杂的程序功能。
类(class)是对象的蓝图或模板,它定义了对象的属性(数据)和行为(方法)。通过类可以创建多个具有相似结构和行为的对象。例如定义一个 Person
类,其对象可以有张三
、李四
等等。
2.5.2、语法说明
2.5.2.1、类的定义
class Person {id: number;name: string;age: number = 18;constructor(id: number, name: string) {this.id = id;this.name = name;}introduce(): string {return `hello,I am ${this.name},and I am ${this.age} years old`}
}
2.5.2.2、对象创建
①语法
创建对象的关键字为new
,具体语法如下
let person = new Person(1,'zhangsan');
②对象属性的访问
console.log(person.name); //读person.name = 'lisi'; //写console.log(person.name);
③对象方法的调用
对象创建后,便可通过对象调用类中声明的方法,如下
let intro = person.introduce();
console.log(intro);
2.5.2.3、静态成员
Typescript 中的类中可以包含静态成员(静态属性和静态方法),静态成员隶属于类本身,而不属于某个对象实例。静态成员通用用于定义一些常量,或者工具方法。
①声明静态成员
定义静态成员需要使用static
关键字。
class Constants{static count:number=1;
}class Utils{static toLowerCase(str:string){return str.toLowerCase();}
}console.log(Constants.count);
console.log(Utils.toLowerCase('Hello World'));
②使用静态成员
静态成员无需通过对象实例访问,直接通过类本身访问即可。
console.log(Constants.count);
console.log(Utils.toLowerCase('Hello World'));
2.5.3、继承
继承是面向对象编程中的重要机制,允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。子类可以直接使用父类的特性,并根据需要添加新的特性或覆盖现有的特性。这种机制赋予面向对象程序良好的扩展性。
class Student extends Person {classNumber: string;constructor(id: number, name: string, classNumber: string) {super(id, name);this.classNumber = classNumber;}introduce(): string {return super.introduce()+`, and I am a student`;}
}let student = new Student(1,'xiaoming','三年二班');
console.log(student.introduce());
注意:
- 类的继承需要使用关键字
extends
- 子类构造器中需使用
super()
调用父类构造器对继承自父类的属性进行初始化。- 在子类中可以使用
this
关键字访问继承自父类的属性和方法。- 在子类中可以使用
super
关键字访问父类定义的方法。
2.5.4、访问修饰符
访问修饰符(Access Modifiers)用于控制类成员(属性、方法等)的可访问性。TypeScript提供了三种访问修饰符,分别是private、protected和public。
class Person {private id: number;protected name: string;public age: number;constructor(id: number, name: string, age: number) {this.id = id;this.name = name;this.age = age;}
}class Student extends Person {}
说明:
- private 修饰的属性或方法是私有的,只能在声明它的类中的被访问。
- protected 修饰的属性或方法是受保护的,只能在声明它的类和其子类中被访问。
- public 修饰的属性或方法是公有的,可以在任何地方被访问到,默认所有的属性和方法都是 public 的。
2.6、接口
2.6.1、接口介绍
接口(interface)是面向对象编程中的另一个重要概念。接口通常会作为一种契约或规范让类(class)去遵守,确保类实现某些特定的行为或功能。
2.6.2、语法说明
①接口定义
接口使用interface
关键字定义,通常情况下,接口中只会包含属性和方法的声明,而不包含具体的实现细节,具体的细节由其实现类完成。
interface Person {id: number;name: string;age: number;introduce(): void;
}
②接口实现
接口的实现需要用到implements
关键字,实现类中,需要包含接口属性的赋值逻辑,以及接口方法的实现逻辑。
class Student implements Person {id: number;name: string;age: number;constructor(id: number, name: string, age: number) {this.id = id;this.name = name;this.age = age;}introduce(): void {console.log('Hello,I am a student');}
}
2.6.3、多态
多态是面相对象编程中的一个重要概念,它可以使同一类型的对象具有不同的行为。下面我们通过一个具体的案例来体会多态这一概念
首先,再创建一个Person
接口的实现类Teacher
,如下
class Teacher implements Person {id: number;name: string;age: number;constructor(id: number, name: string, age: number) {this.id = id;this.name = name;this.age = age;}introduce(): void {console.log('Hello,I am a teacher');}
}
然后分别创建一个Student
对象和一个Teacher
对象,注意两个对象的类型均可以设置Person
,如下
let p1: Person = new Student(1, 'zhangsan', 17);
let p2: Person = new Teacher(2, 'lisi', 35);
最后分别调用p1
和p2
的introduce()
方法,你会发现,同样是Person
类型的两个对象,调用同一个introduce()
方法时,表现出了不同的行为,这就是多态。
p1.introduce();//Hello,I am a student
p2.introduce();//Hello,I am a teacher
2.6.4、接口的作用
在传统的面向对象编程的场景中,接口主要用于设计和组织代码,使代码更加容易扩展和维护。
假如现在需要实现一个订单支付系统,按照面向对象编程的习惯,首先需要定义一个订单类(Order),如下
class Order {totalAmount: number;constructor(totalAmount: number) {this.totalAmount = totalAmount;}pay() {console.log(`AliPay:${this.totalAmount}`);}
}
很容易预想到,这个系统将来可能需要支持其他的支付方式,为了方便代码支持新的支付方式,我们可以对代码进行如下改造。
首先定义一个支付策略的接口,接口中声明一个pay
方法,用来规范实现类必须实现支付逻辑。
interface PaymentStrategy {pay(amount: number): void;
}
然后在订单类中增加一个PaymentStrategy
的属性,并且在订单类中的pay
方法中调用PaymentStrategy
的pay
方法,如下
class Order {totalAmount: number;paymentStrategy: PaymentStrategy;constructor(totalAmount: number, paymentStrategy: PaymentStrategy) {this.totalAmount = totalAmount;this.paymentStrategy = paymentStrategy;}pay() {this.paymentStrategy.pay(this.totalAmount);}
}
这样改造完之后,就可以很容易的在不改变现有代码的情况下,支持新的支付方式了。
比如现在需要支持AliPay
,那我们就可以创建AliPay
这个类(class)并实现(implement)PaymentStrategy
这个接口,如下
class AliPay implements PaymentStrategy {pay(amount: number): void {console.log(`AliPay:${amount}`);}
}
这样一来,之后创建的订单就可以使用AliPay
这个支付方式了。
let order = new Order(1000,new AliPay());
order.pay();
2.6.5、TS中接口的特殊性
TypeScript 中的接口是一个非常灵活的概念,除了用作类的规范之外,也常用于直接描述对象的类型,例如,现有一个变量的定义如下
let person: {name:string, age:number, gender:string} = {name:'张三', age:10, gender:'男'};
可以看到变量的值为一个一般对象,变量的类型为{name:string, age:number, gender:string}
,此时就可以声明一个接口来描述该对象的类型,如下
interface Person {name: string;age: number;gender: string;
}let person: Person = {name:'张三', age:10, gender:'男'};
2.7、枚举
2.7.1、枚举介绍
枚举(Enumeration)是编程语言中常见的一种数据类型,其主要功能是定义一组有限的选项,例如,方向(上、下、左、右)或季节(春、夏、秋、冬)等概念都可以使用枚举类型定义。
2.7.2、语法说明
①枚举定义
枚举的定义需使用enum
关键字,如下
enum Season {SPRING,SUMMER,AUTUMN,WINTER
}
②枚举使用
枚举的使用记住两个原则即可
- 枚举值的访问
像访问对象属性一样访问枚举值,例如
Season.SPRING
- 枚举值的类型
枚举值的类型为
enum
的名称,例如Season.SPRING
和Season.SUMMER
等值的类型都是Season
let spring:Season = Season.SPRING;
③使用场景
现需要编写一个函数move
,其功能是根据输入的方向(上、下、左、右)进行移动,此时就可以先使用枚举定义好所有可能的输入选项,如下
enum Direction {UP,BOTTOM,LEFT,RIGHT
}
move
函数的实现如下
function move(direction: Direction) {if(direction===Direction.UP){console.log('向上移动');}else if(direction===Direction.BOTTOM){console.log('向下移动');}else if(direction===Direction.LEFT){console.log('向左移动');}else{console.log('向右移动');}
}move(Direction.UP);
2.7.3、赋值
在TypeScript 中,枚举实际上是一个对象,而每个枚举值都是该对象的一个属性,并且每个属性都有具体的值,属性值只支持两种类型——数字或字符串。
默认情况下,每个属性的值都是数字,并且从 0
开始递增,例如上述案例中的Direction
枚举中,Direction.UP
的值为0
,Direction.BOTTOM
的值为1
,依次类推,具体如下
console.log(Direction.UP) //0
console.log(Direction.BOTTOM) //1
console.log(Direction.LEFT) //2
console.log(Direction.RIGHT) //3
除了使用默认的数字作为属性的值,我们还能手动为每个属性赋值,例如
enum Direction {UP = 1,BOTTOM = 2,LEFT = 3,RIGHT = 4
}console.log(Direction.UP) //1
console.log(Direction.BOTTOM) //2
console.log(Direction.LEFT) //3
console.log(Direction.RIGHT) //4
再例如
enum Direction {UP = 'up',BOTTOM = 'bottom',LEFT = 'left',RIGHT = 'right'
}console.log(Direction.UP) //up
console.log(Direction.BOTTOM) //bottom
console.log(Direction.LEFT) //left
console.log(Direction.RIGHT) //right
通过为枚举属性赋值,可以赋予枚举属性一些更有意义的信息,例如以下枚举
enum Color {Red = 0xFF0000,Green = 0x00FF00,Blue = 0x0000FF
}enum FontSize {Small = 12,Medium = 16,Large = 20,ExtraLarge = 24
}
2.8、模块化
2.8.1、模块化介绍
模块化是指将复杂的程序拆解为多个独立的文件单元,每个文件被称为一个模块。在 TypeScript 中,默认情况下,每个模块都拥有自己的作用域,这意味着在一个模块中声明的任何内容(如变量、函数、类等)在该模块外部是不可见的。为了在一个模块中使用其他模块的内容,必须对这些内容进行导入、导出。
2.8.2、语法说明
①导出
导出须使用export
关键字,语法如下
export function hello() {console.log('hello module A');
}export const str = 'hello world';const num = 1;
②导入
导入须使用import
关键字,语法如下
import { hello, str } from './moduleA';hello();
console.log(str);
2.8.3、避免命名冲突
若多个模块中具有命名相同的变量、函数等内容,将这些内容导入到同一模块下就会出现命名冲突。例如,在上述案例的基础上,又增加了一个 moduleC,内容如下
export function hello() {console.log('hello module C');
}export const str = 'module C';
moduleB 同时引入 moduleA 和 moduleC 的内容,如下,显然就会出命名冲突
import { hello, str } from "./moduleA";
import { hello, str } from "./moduleC";hello() //?
console.log(str); //?
①导入重命名
import { hello as helloFromA, str as strFromA } from "./moduleA";
import { hello as helloFromC, str as strFromC } from "./moduleC";helloFromA();
console.log(strFromA);helloFromC();
console.log(strFromC);
②创建模块对象
上述导入重命名的方式能够很好的解决命名冲突的问题,但是当冲突内容较多时,这种写法会比较冗长。除了导入重命名外,还可以将某个模块的内容统一导入到一个模块对象上,这样就能简洁有效的解决命名冲突的问题了,具体语法如下
import * as A from "./moduleA";
import * as C from "./moduleC";A.hello();
console.log(A.str);C.hello();
console.log(C.str);
2.8.4、默认导入导出
①默认导出
默认导出允许一个模块指定一个(最多一个)默认的导出项,语法如下
export default function hello(){console.log('moduleA');
}
②默认导入
由于每个模块最多有一个默认导出,因此默认导入无需关注导入项的原始名称,并且无需使用{}
。
import helloFromA from "./moduleA";
由于默认导入时无需关注导入项的名称,所以默认导出支持匿名内容,比如匿名函数,语法如下
export default function () {console.log('moduleB');
}
最后:👏👏😊😊😊👍👍
相关文章:
【鸿蒙 HarmonyOS 4.0】TypeScript开发语言
一、背景 HarmonyOS 应用的主要开发语言是 ArkTS,它由 TypeScript(简称TS)扩展而来,在继承TypeScript语法的基础上进行了一系列优化,使开发者能够以更简洁、更自然的方式开发应用。值得注意的是,TypeScrip…...
Android java基础_异常
一.异常的概念 在Java中,异常(Exception)是指程序执行过程中可能出现的不正常情况或错误。它是一个事件,它会干扰程序的正常执行流程,并可能导致程序出现错误或崩溃。 异常在Java中是以对象的形式表示的,…...
高数考研 -- 公式总结(更新中)
1. 两个重要极限 (1) lim x → 0 sin x x 1 \lim _{x \rightarrow 0} \frac{\sin x}{x}1 limx→0xsinx1, 推广形式 lim f ( x ) → 0 sin f ( x ) f ( x ) 1 \lim _{f(x) \rightarrow 0} \frac{\sin f(x)}{f(x)}1 limf(x)→0f(x)sinf(x)1. (2) lim …...
详解顺序结构滑动窗口处理算法
🎀个人主页: https://zhangxiaoshu.blog.csdn.net 📢欢迎大家:关注🔍点赞👍评论📝收藏⭐️,如有错误敬请指正! 💕未来很长,值得我们全力奔赴更美好的生活&…...
Java 8中使用Stream来操作集合
Java 8中使用Stream来操作集合 在Java 8中,你可以使用Stream API来操作集合,这使得集合的处理变得更加简洁和函数式。Stream API提供了一系列的中间操作(intermediate operations)和终端操作(terminal operations&…...
MATLAB环境下一种改进的瞬时频率(IF)估计方法
相对于频率成分单一、周期性强的平稳信号来说,具有非平稳、非周期、非可积特性的非平稳信号更普遍地存在于自然界中。调频信号作为非平稳信号的一种,由于其频率时变、距离分辨率高、截获率低等特性,被广泛应用于雷达、地震勘测等领域。调频信…...
解决:selenium web browser 的版本适配问题
文章目录 解决方案:使用 webdriver manager 自动适配驱动 使用 selenium 操控浏览器的时候报错: The chromedriver version (114.0.5735.90) detected in PATH at /opt/homebrew/bin/chromedriver might not be compatible with the detected chrome ve…...
pytest.param作为pytest.mark.parametrize的参数进行调用
pytest.param:在 pytest.mark.parametrize 中可以作为一个指定的参数进行调用 获取数据库(网页端)数据,通过pytest.param包装成数据包用于pytest.mark.parametrize 中实现数据驱动调用。 import os import pytest import json fr…...
如何判断一个元素是否在可视区域中?
文章目录 一、用途二、实现方式offsetTop、scrollTopgetBoundingClientRectIntersection Observer创建观察者传入被观察者 三、案例分析参考文献 一、用途 可视区域即我们浏览网页的设备肉眼可见的区域,如下图 在日常开发中,我们经常需要判断目标元素是…...
Go Run - Go 语言中的简洁指令
原文:breadchris - 2024.02.21 也许听起来有些傻,但go run是我最喜欢的 Go 语言特性。想要运行你的代码?只需go run main.go。它是如此简单,我可以告诉母亲这个命令,她会立即理解。就像 Go 语言的大部分功能一样&…...
Spring全面精简总结
Spring两大核心功能:IOC控制反转、AOP面向切面的编程 控制反转(loC,Inversion of Control),是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。控制反转就是…...
低代码开发如何助力数字化企业管理系统平台构建
随着数字化时代的到来,企业对于管理系统的需求日益增长。高效的管理系统可以提高企业的运作效率,降低成本,提升竞争力。然而,传统的开发方式在应对日益复杂的管理系统需求时,显得力不从心。低代码开发作为一种新兴的开…...
ElasticSearch之零碎知识点
写在前面 本文记录es的零碎知识点,包括但不限于概念,集群方式,等。 1:词项查询 VS 全文查询 词项查询:查询的内容不做分词处理,输入的什么查询什么。 全文查询:查询的内容会做分词处理&…...
【春运抢票攻略浅析】
参考 最全12306放票规则,抢票策略,候补作用2023年12306抢票攻略(纯技巧) 研究放票规则,候补的时候车次进行一下挑选,能够买长乘短的尽量买长,不要候补一些区间票吧,这是一开始放票…...
【Java EE初阶二十五】简单的表白墙(一)
1. 前端部分 1.1 前端代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"wid…...
人工智能的新浪潮:探索OpenAI的Sora视频模型及其对未来创作的影响
OpenAI的最新AI视频模型Sora,自发布以来,已成为科技界的热点。Sora的核心能力在于将文本描述转化为高清视频片段,标志着在视频生成领域的一次重大突破。Sora的特点包括使用深度理解语言的能力来准确解释提示,以及生成表达丰富情感…...
【c语言】字符函数和字符串函数(上)
前言 在编程的过程中,我们经常要处理字符和字符串,为了⽅便操作字符和字符串,C语⾔标准库中提供了⼀系列库函数~ 欢迎关注个人主页:逸狼 创造不易,可以点点赞吗~ 如有错误,欢迎指出~ 目录 前言 1. 字符分…...
React18源码: schedule任务调度messageChannel
React调度原理(scheduler) 在React运行时中,调度中心(位于scheduler包)是整个React运行时的中枢(其实是心脏),所以理解了scheduler调度,就基本掌握了React的核心React两大循环:从宏…...
Jmeter 学习目录
Jmeter 所有内容均以学习为主输出内容,按照最小单位和基础进行输出。 如果有看不懂,或者有不明确的内容,欢迎大家留言说明。 Jmeter系列(1)Mac Jmeter下载安装启动 Jmeter系列(2)Jmeter 目录介…...
计算机网络 数据链路层课后题
1.以太网帧有哪些不同的封装格式?他们有何区别和应用场景? 以太网II封装(Ethernet II):以太网II封装是最常用的以太网封装格式,也被称为DIX封装。它在数据链路层首部使用6个字节的目的MAC地址和6个字节的源…...
实现验证码功能
Kaptcha 文章目录 Kaptcha介绍插件使用介绍原理引入依赖生成验证码 验证码小项目初始化前端代码约定前后端交互接口接口定义 介绍 Kaptcha 是Google的⼀个⾼度可配置的实⽤验证码⽣成⼯具 https://code.google.com/archive/p/kaptcha ⽹上有很多⼈甚⾄公司基于Google的kaptc…...
PyQt6的开发流程(密码生成小程序为例)
PyQt6的开发流程(密码生成小程序为例) 文章目录 PyQt6的开发流程(密码生成小程序为例)一、流程介绍与概览1. 界面与逻辑分离的开发流程2. PyQt6的开发流程 二、打开 designer.exe 创建文件三、用QT设计师绘制界面保存成ui1. QT常用…...
思腾云计算中心 | 5千平米超大空间,基础设施完善,提供裸金属GPU算力租赁业务
2021年,思腾合力全资收购包头市易慧信息科技有限公司,正式开启云计算业务。思腾云计算中心占地2400平米,位于包头市稀土高新区,毗邻多家知名企业,地理位置优越,交通便利,是区内重要的信息化产业…...
【Leetcode每日一题】二分查找 - 在排序数组中查找元素的第一个和最后一个位置(难度⭐⭐)(18)
1. 题目解析 Leetcode链接:34. 在排序数组中查找元素的第一个和最后一个位置 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 核心在于找到给定目标值所在的数组下标区间,设计一个O(logn)的算法。 2. 算法原…...
远程连接 vscode 出错 “远程主机可能不符合 glibc 和 libstdc++ VS Code 服务器的先决条件”
原因: vscode 版本是 1.86,服务器上的 glibc 和 libstdc 版本不满足 要求(2.28 和 3.4.25)。 解决: 1、下载 1.85.2,解压直接运行 Code.exe。 2、回退 Remote-ssh 到 0.107.1。 参考: vscode 1.86版本远程ssh不兼容旧…...
Maven入门:Java项目构建和管理的利器
Maven入门:Java项目构建和管理的利器 Maven 是一个项目管理和综合工具,它基于项目对象模型(POM)概念。Maven 可以管理项目的构建、报告和文档。以下是一篇介绍 Maven 配置和应用的教程文章。 Maven简介 Maven 使用其核心概念 POM…...
《游戏引擎架构》 -- 学习4
资源及文件系统 文件系统 游戏引擎的文件系统API通常提供以下功能: 搜需路径:是含一串路径的字符串,各路径之间以特殊字符(如冒号或分号)分隔,找文件时就会从这些路径进行搜寻。例如在命令行下执行程序&a…...
Wagtail安装运行并结合内网穿透实现公网访问本地网站界面
文章目录 前言1. 安装并运行Wagtail1.1 创建并激活虚拟环境 2. 安装cpolar内网穿透工具3. 实现Wagtail公网访问4. 固定的Wagtail公网地址 正文开始前给大家推荐个网站,前些天发现了一个巨牛的 人工智能学习网站, 通俗易懂,风趣幽默…...
10分钟快速开始SkyWalking结合Springboot项目
10分钟快速开始SkyWalking结合Springboot项目 实习期间,公司让我去学习一下链路追踪如何集成到Springboot项目中。 为此有两个方案: 1.opentelementryjaegerprometheus opentelementry 收集器收集线上的metrics和traces,然后发送给jaeger和p…...
STM32—触摸键
目录 1 、 电路构成及原理图 2 、编写实现代码 3、代码讲解 4、烧录到开发板调试、验证代码 5、检验效果 此笔记基于朗峰 STM32F103 系列全集成开发板的记录。 1 、 电路构成及原理图 触摸键简单的了解就是一次电容的充放电过程。从原理图可以看出,触摸键 …...
大学生创新创业大赛的意义/广州百度搜索排名优化
如前一节所述,通过训练确定滤波器矩阵的值。 As addressed in the previous section, thevalues of the filter matrix are determined through the training process. 因此,这些值在整个训练过程中不断训练。 Therefore, these values are continuou…...
苹果园做网站的公司/爱战网关键词挖掘查询工具
这可真不是一个人干的活儿啊转载于:https://blog.51cto.com/colinshares/410833...
搭建自己的网站需要什么/免费行情网站的推荐理由
如何优雅的查看电脑账户免密码1.情况描述:比如以下这种情况,我们想要得到看到登陆密码。2.解决方案1.情况描述:比如以下这种情况,我们想要得到看到登陆密码。 2.解决方案 当然这可以使用浏览器的密码管理功能可以看到,…...
删除wordpress 后台/seo面试常见问题及答案
点击蓝字关注我们案例一:入职表不等于劳动合同【基本案情】2019年4月9日,王某入职某公司从事会计工作。入职时,王某填写《员工入职表》,填写了个人情况、家庭情况及简历等,公司总经理签字确认。双方未签订书面劳动合同…...
用前端框架做自适应网站/网站搜索排名优化
1 TreeMap 实战在创建 TreeMap 对象时,如果使用参数为空的构造方法,则根据 Map 对象的 key 进行排序(key必须实现Comparable接口);如果使用参数为 Comparator 的构造方法,则根据 Comparator对key 进行排序。方式一:自然…...
自己做的电影网站打开很慢/营销手段
python中自带了处理python的模块,使用时候直接import json即可。 使用loads方法即可将json字符串转换成python对象,对应关系如下: JSON Python object dict array list string unicode number (int) int, long number (real) float true True…...