TypeScript 泛型

面试题-TS(六):TypeScript 中的泛型是什么? 泛型是一种类型参数化的方式,它允许我们在函数、类、接口等代码中定义一个或多个类型参数,而这些参数在使用时并不指定具体的数据类型。在调用函数或实例化类时,我们可以通过传递不同的数据类型来使用相同的泛型代码。TypeScript中的泛型使用尖括号(<>)来表示,并可以使用任意标识符来表示类型参数。return arg;在上面的示例中,<T>表示类型参数,它允许我们在函数调用时传递不同的数据类型。 阅读详情

在 TypeScript 中,泛型是一种在定义函数、类、接口等时,不预先指定具体的数据类型,而是在使用时再指定的机制。
注意:无法创建泛型枚举和泛型命名空间。

创建一个identity函数, 这个函数会返回任何传入它的值。

function identify(arg) {
  return arg
}

TypeScript 编译器会自动推断arg的类型是any。
使用any类型会导致这个函数可以接收任何类型的arg参数,这样就丢失了一些信息:传入的类型与返回的类型应该是相同的。
如果我们传入一个数字,我们只知道任何类型的值都有可能被返回。
比如:

function identify(arg: any): any {
  return `${arg}`
}
console.log( identify('aa') );  // a
console.log( identify(123) );   // 123
console.log( identify({"name": "张三"}) ); // [object Object]

因此,我们需要一种方法使返回值的类型与传入参数的类型是相同的。 这里,我们使用了 类型变量,它是一种特殊的变量,只用于表示类型而不是值。

function identity<T>(arg: T): T {
    return arg;
}

let output1 = identity<string>("Hello"); 
let output2 = identity("Hello");

identity 函数是一个泛型函数,T 是一个类型参数。
T捕获用户传入的类型。使用T 作为参数类型 和 返回值类型。这样,参数类型与返回值类型是相同的,允许跟踪函数里使用的类型的信息。
identity<string>("Hello") 明确的指定了T是string类型,并做为一个参数传给函数,使用了<>括起来而不是()。传入string类型并返回string类型。

identity("Hello") 没有明确指定类型。编译器会根据传入的参数自动地确定T的类型(类型推论)。

identity函数叫做泛型,适用于多个类型,它不会丢失信息,保持类型的准确性,传入的参数类型与 返回数值类型 相同。

使用泛型变量

以 identity 函数为例,它只是简单地返回传入的参数,因为泛型 T 可以是任意类型,所以不能随意假设它具有某些特定的属性或方法,比如 length 。
如果操作的 T 类型是数字,数字是没有 .length属性的:

function identity<T>(arg: T): T {
  console.log(arg.length); // Error: Property 'length' does not exist on type 'T'.
  return arg;
}

let output1 = identity<number>(123);

如果操作的是 T 类型的数组(T[] 或 Array<T> ),因为数组是有 length 属性的,所以这样的操作就是合法且类型安全的。

function identity<T>(arr: T[]): void {
    console.log(`数组长度: ${arr.length}`); 
}
identity<string>(["a", "b", "c"]); // 数组长度: 3
identity<number>([1, 2, 3, 5]); // 数组长度: 4

identity 函数可以正确地处理不同类型的数组,并且由于操作的是数组,使用 length 属性是合法且类型安全的。

泛型函数的类型

泛型函数的类型可以通过类型参数和函数参数及返回值的类型来描述。

示例:

function identity<T>(arg: T): T {
  return arg;
}

// 类型表示
let myIdentity: <T>(arg: T) => T = identity;

// 调用
let result1 = myIdentity<number>(5); 
let result2 = myIdentity<string>("Hello"); 

myIdentity 的类型被声明为 <T>(arg: T) => T ,表示这是一个接受一个类型为 T 的参数并返回类型为 T 的结果的泛型函数类型。
let myIdentity: <T>(arg: T) => T = identity; 是在为变量 myIdentity 进行类型声明和赋值。
具体解释如下:

  • let myIdentity :声明一个名为 myIdentity 的变量。
  • <T>(arg: T) => T :这是函数类型的描述。其中 <T> 表示这是一个泛型函数,T 是类型参数。(arg: T) 表示函数接受一个类型为 T 的参数 arg ,=> T 表示函数的返回值类型也是 T 。
  • = identity :将已经定义的泛型函数 identity 赋值给变量 myIdentity 。
    总的来说,这行代码表明 myIdentity 是一个与 identity 函数具有相同类型签名(接受一个泛型参数并返回相同类型的值)的变量,并将 identity 函数的值赋给了它。

可以使用不同的泛型参数名,只要在数量上和使用方式上能对应上就可以:

// 类型表示
let myIdentity: <U>(arg: U) => U = identity;

可以使用带有调用签名的对象字面量来定义泛型函数:

function identity<T>(arg: T): T {
    return arg;
}

// 类型表示
let myIdentity: {<T>(arg: T): T} = identity;
my

myIdentity 的类型被描述为 {<T>(arg: T): T} ,表示这是一个接受一个泛型参数 arg 并返回相同类型的函数。

泛型函数可以有多个参数:

function combine<T>(item1: T, item2: T): T[] {
  return [item1, item2];
}

// 类型表示
let myCombine: <T>(item1: T, item2: T) => T[] = combine;
console.log( myCombine(10, 15) );
console.log( myCombine("hello", "world") );

myCombine 的类型被声明为 <T>(item1: T, item2: T): T[] ,表示接受两个类型为 T 的参数,并返回一个类型为 T 的数组。
注意: item1 的类型必须与 item2 的类型一致。

假如有一个泛型函数接受两个参数,一个是泛型类型,另一个是固定类型:

function combineData<T>(data: T, fixedValue: string): T {
  // 在进行操作前,必须先进行类型断言或类型缩小的检查
  if (typeof data === 'string') {
    return (data + fixedValue) as T;
  } else if (typeof data === 'number') {
    return Number(data.toString() + fixedValue) as T;
  } else {
    throw new Error('不支持的类型');
  }
}

// 类型表示
let myCombinedData: <T>(data: T, fixedValue: string) => T = combineData;

// 调用示例
let result1 = combineData<number>(10, '5'); // 105
let result2 = combineData<string>('Hello', ' World'); //  "Hello World" 

在这个示例中,第一个参数是泛型类型,第二个参数是固定类型,两个参数类型不同,在进行操作前,必须先进行类型断言或类型缩小的检查。
否则,会报错:参数类型不兼容。

可以使用泛型函数生成元组数据:

function createTuple<A, B>(first: A, second: B): [A, B] {
    return [first, second];
}

// 类型表示
let CreateTupleFunction: <A, B>(first: A, second: B) => [A, B] = createTuple;
// 调用示例
let tuple1 = CreateTupleFunction<number, string>(10, "Hello");
console.log(tuple1); // [10, "Hello"]

// 也可以直接调用方法:
let tuple2 = createTuple<string, boolean>("World", true);
console.log(tuple2); // ["World", true] 

泛型类

泛型类可以在创建类时不指定某些类型,而是在实例化类的时候再确定。

class GenericBox<T> {
  private content: T;

  constructor(value: T) {
    this.content = value;
  }

  getContent(): T {
    return this.content;
  }

  setContent(value: T) {
    this.content = value;
  }
}

// 使用示例
let box1 = new GenericBox<number>(10);  // 类型是number,后续操作参数只能是number
console.log(box1.getContent());  // 输出: 10

let box2 = new GenericBox<string>("Hello");
console.log(box2.getContent());  // 输出: "Hello"

GenericBox 是一个泛型类,T 是类型参数。在创建类的实例时,指定具体的类型(如 number 或 string )。
let box1 = new GenericBox<number>(10);指定实例 box1 的类型是 number ,类型不可以改变。

泛型接口

可以定义具有泛型类型参数的接口。
示例:

interface KeyValuePair<K, V> {
  key: K;
  value: V;
}

// 使用示例
let stringNumberPair: KeyValuePair<string, number> = {
  key: "id",
  value: 123
};

let booleanStringPair: KeyValuePair<boolean, string> = {
  key: true,
  value: "active"
};

在上述示例中,KeyValuePair 是一个泛型接口,K 表示 key 的类型,V 表示 value 的类型。

再看一个更复杂的泛型接口示例,比如一个用于操作数组的接口:

interface ArrayOperations<T> {
  push(item: T): void;
  pop(): T | undefined;
  getAtIndex(index: number): T | undefined;
}

class MyArray<T> implements ArrayOperations<T> {
  private items: T[] = [];

  push(item: T): void {
    this.items.push(item);
  }

  pop(): T | undefined {
    return this.items.pop();
  }

  getAtIndex(index: number): T | undefined {
    return this.items[index];
  }
}

let numberArray = new MyArray<number>();
numberArray.push(10);
numberArray.push(20);

let stringArray = new MyArray<string>();
stringArray.push("Hello");
stringArray.push("World");

在这个示例中,ArrayOperations 是一个泛型接口,定义了对数组的一些常见操作。MyArray 类实现了这个接口,用于处理特定类型的数组。

泛型约束

在 TypeScript 中,泛型约束用于对泛型类型参数施加一定的条件限制,以确保在使用泛型时具有某些特定的属性或方法。
创建一个包含 .length属性的接口,使用这个接口和extends关键字来实现约束:

interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length);
  return arg;
}

let myString = loggingIdentity('hello');  // 正确,'string' 具有 'length' 属性
let myArray = loggingIdentity([1, 2, 3]);  // 正确,数组具有 'length' 属性
let myObj = loggingIdentity({length: 10, value: 3});  // 正确,具有 'length' 属性

// 以下会报错,因为数字类型没有 'length' 属性
// Error: Argument of type 'number' is not assignable to parameter of type 'Lengthwise'.
let myNumber = loggingIdentity(5);  

在泛型约束中使用类型参数

// 接口定义了一个对象类型,属性名的类型是string,属性值的类型由类型参数 T 决定。
interface Person<T> {
  [key: string]: T;
}
// 将 ObjType 约束为 Person 接口类型
// 需要明确 Person 类的值的类型(明确T),设为any
// 不知道返回值的类型,也定为 any
function getProperty<ObjType extends Person<any>>(
  obj: ObjType,
  propName: keyof ObjType & string
): any {
  if (propName in obj) {
    return obj[propName];
  } else {
    throw new Error(`属性 '${propName}' 不在对象中`);
  }
}

// 将 person 的类型指定为 Person<string> ,表示 Person 接口中的属性值都是字符串类型。
let person: Person<string> = {
  name: "Alice",
  likes: "dog"
};
console.log( getProperty(person,'name') );

// 将 person1 的类型指定为 Person<number> ,表示 Person 接口中的属性值都是number类型。
let person1: Person<number> = {
  age: 25,
  salary: 10000
};
console.log( getProperty(person1,'salary') );

在泛型中使用类类型

在TypeScript使用泛型创建工厂函数时,需要引用构造函数的类类型。

示例:

class Vehicle {
  wheels: number;

  constructor(wheels: number) {
    this.wheels = wheels;
  }
}

class Car extends Vehicle {
  color: string;

  constructor(wheels: number, color: string) {
    super(wheels);
    this.color = color;
  }
}

class Motorcycle extends Vehicle {
  engineCapacity: number;

  constructor(wheels: number, engineCapacity: number) {
    super(wheels);
    this.engineCapacity = engineCapacity;
  }
}

// 构造函数
function createVehicle<T extends Vehicle>(ctor: new (arg: any) => T, arg: any): T {
  return new ctor(arg);
}

// 创建汽车实例
let myCar = createVehicle(Car, { wheels: 4, color: 'red' });
console.log(myCar.color); 

// 创建摩托车实例
let myMotorcycle = createVehicle(motorcycle, { wheels: 2, engineCapacity: 500 });
console.log(myMotorcycle.engineCapacity); 
  • 定义了 Vehicle 基类以及 Car 和 Motorcycle 派生类。
  • createVehicle 是一个泛型工厂函数,它接受一个类的构造函数 ctor 和参数 arg ,用于创建指定类型的实例:
    • <T extends Vehicle> :这是泛型部分,表示 T 是一个类型参数,并且它必须是 Vehicle 类或继承自 Vehicle 类的类型。
    • ctor: new (arg: any) => T :这是函数的第一个参数。它是一个构造函数,接受一个类型为 any 的参数 arg ,并且这个构造函数创建的对象类型是由泛型 T 确定的。
    • arg: any :这是函数的第二个参数,类型为 any ,将作为第一个参数(构造函数)的输入。
    • : T :这指定了函数的返回值类型为泛型 T ,即通过传入的构造函数创建并返回指定类型的对象。
    • return new ctor(arg); :创建一个(作为参数传入的) 类的实例。
Typescript:泛型 阅读详情

相关推荐

ESP32Servo库驱动SG90舵机:从入门到精准控制

本文详细介绍了如何使用ESP32Servo库驱动SG90舵机,从硬件连接到软件环境搭建,再到编写示例程序实现精准控制。内容涵盖库安装、基础驱动代码解析、舵机校准方法以及平滑运动控制,帮助开发者快速掌握ESP32控制舵机的核心技能,并提供了电源管理、信号抗干扰等实用避坑指南。

ik678901的博客 897

TypeScript - 泛型解析Generics

泛型 主要用于创建重用组件,允许用户去使用自己的类型去重用这些组件。 如何定义泛型? function identity<T>(arg: T): T { return arg; } 对比一下 function identity(arg: any): any { return arg; } 就很容易理解了,实际上就是运用了一个变量T去捕捉用户提供的类型 (例如: nu...

莫小猪的菜鸟进阶路 406

音频功放电路大全

作为硬件工程师,特别是做纯粹模拟电路、应用于音频功放的工程师,对于A类,B类,AB类,D类,G类,H类,T类功放应该特别熟悉。大多数工程师或许只知道其中的一部分、或者知道大概,为了让更多的工程师掌握更加详尽的音频功放知识,下文对以上说的音频功放做详细的说明。 功放,顾名思义,就是功率放大的缩写。与电压或者电流放大来说,功放要求获得一定的、不失真的功率,一般在大信号状态下工作,因此,功放电路一般包含电压放大或者电流放大电路没有的特殊问题,具体表现在:①输出功率尽可能大;②通常在大信号状态下工作;③非线性失真突

ltqdxl的博客 6595

TypeScript -- 泛型

TypeScript -- 泛型

Mr_Wanter 1328

高速电路的信号完整性分析

摘要:介绍了高速PCB设计中的信号完整性概念以及破坏信号完整性的原因,从理论和计算的层面上分析了高速电路设计中反射和串扰的形成原因,并介绍了IBIS仿真。 关键词:信号完整性 反射 串扰 IBIS仿真 随着半导体技术和深压微米工艺的不断发展,IC的开关速度目前已经从几十MHz增加到几百MHz,甚至达到几GHz。在高速PCB设计中,工程师经常会碰到误触发、阻尼振荡、过冲、欠冲、串...

bh_wang的专栏 1431

AI一键生成带货短视频:电商直播的未来

随着电子商务行业的快速发展,直播带货已成为一种极为有效的营销手段。然而,传统的人工直播方式存在诸多局限性,如人力成本高、主播培训周期长等问题。为了解决这些挑战,一种基于AI技术的一键生成带货视频解决方案应运而生——这就是“Anchor Crafter”。这项创新技术不仅能够自动创建高质量的带货视频,而且还能实现人物与商品之间的自然交互,极大地提升了用户体验。

这里汇聚了前沿的技术分享与实用的开发技巧,带你探索从创意到企业的技术创业之路。 2204

TypeScript——14.泛型类

TypeScript 中的泛型类(Generic Classes)是一种允许你在类中使用类型参数的类。这意味着你可以在定义类时不确定某些类型,而是在实例化类时才指定具体的类型。这样可以使类更加灵活和可重用。基本概念泛型类在类名后面使用尖括号 < T> 声明类型参数(T 是约定俗成的占位符,可以自定义名称)。这个类型参数可在类内部作为具体类型使用。

weixin_63215361的博客 268

海康VisionMaster与西门子Smart 200进行S7通信

海康VisionMaster与西门子Smart 200进行S7通信

haier123888的博客 8180

typescript 泛型详解

但是,该函数只接收数值类型,无法用于其他类型为了能让函数能够接受任意类型,可以将参数类型修改为 any。泛型在保证类型安全(不丢失类型信息)的同时,可以让函数等与多种不同的类型一起工作,灵活可复用。泛型是TypeScript中的一种工具,它允许你创建可重用的组件,这些组件可以在多种类型上工作,而不仅仅是一个类型。如上图,当输入的是一个字符串hello时,ts会推论出它是hello这种字面量类型,但是其实我们不是想要这种类型,我们是想要字符串类型,这时候就需要显示的传入类型参数,

JiuMeilove的博客 3891

VS2022编译xlnt库

xlnt是一个用于读写Excel文件的C++库,本文介绍如何用源代码编译静态或动态xlnt库

QQVQQ的博客 7288

6、深入解析Microsoft 365核心服务对比与迁移策略

本文深入解析了Microsoft 365的核心服务,包括身份和设备管理、现代设备配置体验、Exchange和SharePoint的迁移策略以及Microsoft Teams的协作功能。同时探讨了迁移过程中需要考虑的安全控制措施,为组织规划和实施云迁移项目提供了全面的指导和建议。

k8s6orchestrator的博客 107

Typescript中的泛型

泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。这种特性可以极大地增加代码的灵活性和可重用性。// 不使用泛型的例子 - 只能返回数字类型return arg;// 使用泛型的例子 - 可以返回任何类型Treturn arg;// 使用示例string// 类型为 stringnumber(100);// 类型为 number简单场景:优先使用单字母标识符 (T, K, V 等)复杂场景。

2401_88174794的博客 2107

深度学习图神经网络 (GNN) —— 处理图结构数据(六十九)

本文系统介绍了图神经网络(GNN)的核心概念、主流模型及其应用。主要内容包括: GNN基础:阐述了图结构数据的特性(节点数不定、连接不规则),以及GNN相比CNN/RNN的优势在于处理非欧式空间的图数据。 核心机制:重点讲解了消息传递框架(MPNN),通过聚合邻居信息迭代更新节点表示,并分析了GCN的归一化邻接矩阵计算和GAT的注意力权重机制。 典型模型: GCN:基于归一化邻接矩阵的特征传播 GAT:引入注意力机制区分邻居重要性 GraphSAGE:通过采样解决大图扩展性问题 GIN:理论表达能力最强的图

hello.reader 300

【TypeScript】泛型详解

在软件工程中,构建具有一致 API 且可重用的组件是非常重要的目标之一。我们希望这些组件不仅能处理当前的数据,还能处理未来可能出现的不同类型的数据。为了实现这一目标,许多编程语言都提供了泛型功能。在像 C# 和 Java 这样的语言中,泛型是创建可重用组件的主要工具之一。泛型允许我们编写能够处理多种类型的组件,而不是仅限于某一种特定类型。通过这种方式,开发者可以利用泛型来构建能够适应不同数据类型的通用组件,避免重复编写大量类似的代码。

lph159的博客 2804

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

学习TypeScript14(泛型)

泛型在TypeScript 是很重要的东西 例如vue3 是用ts编写的 里面用到了非常多的泛型 ok:我们看一个小例子 我写了两个函数一个是数字类型的函数,另一个是字符串类型的函数,其实就是类型不同, 实现的功能是一样的,这时候我们就可以使用泛型来优化 function num (a:number,b:number) : Array<number> { return [a ,b]; } num(1,2) function str (a:string,b:string) : A

qq1195566313的博客 1万+

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

TypeScript——泛型

泛型是什么?有什么作用?

hhtfhtf的博客 4855

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

typeScript泛型

泛型 泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。 我们可以用一个函数createArray,它可以创建一个指定长度的数组,同时将每一项都填充一个默认值: function createArray(length: number, value: any): Array<any> { let result = []; for (let i = 0; i < length; i++) { res

YangJing17的博客 5504

TypeScript 泛型-泛型类型

源码 ts //声明一个泛型类型的函数 function Hello<T>(arg:T):T { return arg; } //声明一个方法该方法引用上面的泛型类型的函数 let myHello:<T>(arg:T) => T = Hello; alert(myHello('xiaochuan')); HTML <!DOCTYPE html...

嘿嘿 1859

「TypeScript系列」TypeScript 泛型

泛型类和泛型方法的主要区别在于它们的作用域和使用方式。泛型类在整个类的作用域内都有效,而泛型方法仅在方法的作用域内有效。在使用时,泛型类需要在创建对象时指定类型参数,而泛型方法可以在调用时指定或省略类型参数。在 TypeScript 中,虽然没有直接的“泛型类”语法,但你可以通过泛型接口来模拟泛型类的行为。泛型方法和泛型函数在本质上是相同的,都是直接在函数签名中定义类型参数,并在函数体内部使用这些类型参数。

日常笔记/总结/系列知识梳理 1550

【TypeScript】泛型详解与应用

泛型函数是指一种能够处理不同类型数据的函数。在定义函数时,我们通常会指定参数和返回值的类型。然而,如果我们希望函数能够处理多种类型的数据,就需要使用泛型。泛型允许我们在函数、接口或类定义时暂时指定类型,并在函数调用时传入具体的类型。例如,以下是一个简单的泛型函数identityreturn arg;return arg;return arg;在上述代码中,Type是一个泛型变量,表示该函数可以处理任意类型的数据。string与普通函数类似,泛型函数的类型定义也可以包含类型参数。

lph159的博客 1628

关于TypeScript泛型的解释

今天让我们一起来学习什么是泛型以及它在TypeScript(TS)中的使用方式。 泛型:一种抽象类型的能力 TS中泛型的实现使我们能够创建可重用的组件,一个组件可以支持多种类型的数据,为代码添加额外的抽象层和可重用性。泛型可以应用于TS中的函数、接口和类。 本文将会解释泛型是什么以及用一系列变量的例子来阐述如何运用。 泛型之Hello World 用一个简单的例子来阐述泛型的概念,假如我们有一个...

前端技术小哥 4793

TypeScript:泛型

给identity3添加了类型变量T。 T帮助我们捕获用户传入的类型(比如:number),之后我们就可以使用这个类型。 之后我们再次使用了 T当做返回值类型。现在我们可以知道参数类型与返回值类型是相同的了。 这允许我们跟踪函数里使用的类型的信息。

ChinaDragon10的博客 1276

TypeScript 泛型及应用

在以上代码中,首先通过 keyof T 拿到 T 的所有属性名,然后使用 in 进行遍历,将值赋给 P,最后通过 T[P] 取得相应的属性值。中间的?号,用于将所有属性变为可选。如果 T 能赋值给 U 类型的话,那么就会返回 never 类型,否则返回 T 类型。最终实现的效果就是将 T 中某些属于 U 的类型移除掉。

kang_k的博客 1349

TypeScript 泛型介绍

泛型 泛型,顾名思义,就是可以适用于多个类型,使用类型变量比如T帮助我们捕获传入的类型,之后我们就可以继续使用这个类型。 本质是参数化类型,通俗的将就是所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和函数的创建中,分别成为泛型类,泛型接口、泛型函数 泛型-泛型函数 创建泛型函数的格式 function fn<Type>(value: Type): Type { return value } // 上面的Type只是一个名字而已,可以改成其他的 function fn

weixin_58207509的博客 1709
上一篇: TypeScript 函数
下一篇: TypeScript 类型保护与区分类型
fishmemory7sec
博客等级 码龄5年 1165粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值