Rust之包,箱和模块管理(四):用use关键字引用其他包

Rust语言基础教程学习【六】(包、Crate、模块) 当编写大型程序时,组织代码显得尤为重要。通过对相关功能进行分组和划分不同功能的代码,可以清楚在哪里可以找到实现了特定功能的代码,以及在哪里可以改变一个功能的工作方式。到目前为止,我们编写的程序都在一个文件的一个模块中。伴随着项目的增长,你应该通过将代码分解为多个模块和多个文件来组织代码。 阅读详情

开发环境

  • Windows 10
  • Rust 1.63.0

 

  •  VS Code 1.70.2 

    项目工程

这里继续沿用上次工程rust-demo

 用use关键字将路径带入范围

不得不写出调用函数的路径可能会感到不方便和重复。在之前的例子中,无论我们选择add_to_waitlist函数的绝对路径还是相对路径,每次我们想调用add_to_waitlist时,我们都必须指定front_of_house和hosting。幸运的是,有一种方法可以简化这个过程:我们可以用use关键字创建一个路径的快捷方式,然后在作用域中的其他地方使用更短的名称。

在下例种,我们将crate::front_of_house::hosting模块纳入eat_at_restaurant函数的范围,因此我们只需指定hosting::add_to_waitlist来调用eat_at_restaurant中的add_to_waitlist函数。

文件名:src/lib.rs

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

use crate::front_of_house::hosting;     // use关键字引入crate::front_of_hosue::hosting模块

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}

在作用域中添加使用和路径类似于在文件系统中创建符号链接。通过在箱crate根中添加use crate::front _ of _ house::hosting,hosting现在是该范围内的有效名称,就像在箱crate根中定义了托管模块一样。与任何其他路径一样,被纳入使用范围的路径也会检查隐私。 

请注意,use只为发生使用的特定范围创建快捷方式。下例种将eat_at_restaurant函数移动到一个名为customer的新的子模块中,这个子模块与use语句的作用域不同,所以函数体不会编译:

文件名:src/lib.rs

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

use crate::front_of_house::hosting;

mod customer {                  // 模块customer
    pub fn eat_at_restaurant() {
        hosting::add_to_waitlist();
    }
}

编译器错误显示快捷方式在客户模块中不再适用:

$ cargo build
   Compiling restaurant v0.1.0 (file:///projects/restaurant)
error[E0433]: failed to resolve: use of undeclared crate or module `hosting`
  --> src/lib.rs:11:9
   |
11 |         hosting::add_to_waitlist();
   |         ^^^^^^^ use of undeclared crate or module `hosting`

warning: unused import: `crate::front_of_house::hosting`
 --> src/lib.rs:7:5
  |
7 | use crate::front_of_house::hosting;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

For more information about this error, try `rustc --explain E0433`.
warning: `restaurant` (lib) generated 1 warning
error: could not compile `restaurant` due to previous error; 1 warning emitted

请注意,还有一个警告,该use不再用于其作用域!要解决这个问题,也在customer模块内移动use,或者在子customer模块内用super::hosting引用父模块中的快捷方式。

创建惯用的使用路径

在之前的例子中,你可能想知道为什么我们指定use crate::front _ of _ house::hosting,然后在eat_at_restaurant中调用hosting::add_to_waitlist,而不是指定一直到add_to_waitlist函数的use路径来达到相同的结果,如下例

文件名:src/lib.rs

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

use crate::front_of_house::hosting::add_to_waitlist;   // use指定到具体的函数

pub fn eat_at_restaurant() {
    add_to_waitlist();
}

尽管之前的例子和上面的例子完成了相同的任务,但是之前的例子是将函数引入use范围的惯用方式。将函数的父模块纳入use范围意味着我们必须在调用函数时指定父模块。在调用函数时指定父模块可以清楚地表明函数不是本地定义的,同时还可以最大限度地减少完整路径的重复。上面的例子中的代码不清楚add_to_waitlist是在哪里定义的。

另一方面,当使用use引入结构、枚举和其他项时,习惯上指定完整路径。下例种显示了将标准库的HashMap结构引入二进制crate的惯用方法。

文件名:src/main.rs

use std::collections::HashMap;    // use标准库HashMap

fn main() {
    let mut map = HashMap::new();
    map.insert(1, 2);
}

这个习惯用法背后没有什么强有力的理由:这只是已经出现的惯例,人们已经习惯了以这种方式阅读和编写Rust代码。

这个习惯用法的例外是,如果我们用use语句将两个同名的项目带入作用域,因为Rust不允许这样做。下例种显示了如何将两个同名但父模块不同的Result类型引入作用域,以及如何引用它们。

文件名:src/lib.rs

use std::fmt;
use std::io;

fn function1() -> fmt::Result {
    // --snip--
    Ok(())
}

fn function2() -> io::Result<()> {
    // --snip--
    Ok(())
}

正如您所看到的,使用父模块区Result类型。如果我们指定use std::fmt::Result和use std::io::Result,我们将在同一个范围内有两种Result类型,Rust在使用Result时不知道我们指的是哪一种。

使用as关键字提供新名称

这里有另一个解决方法,可以将两个同名的类型放在同一个作用域中use:在路径后面,我们可以为类型指定as和一个新的本地名称或别名。下例显示了编写上例中代码的另一种方法,用as重命名两种Result类型中的一种。

文件名:src/lib.rs

use std::fmt::Result;
use std::io::Result as IoResult;       // as关键字,别名       

fn function1() -> Result {
    // --snip--
    Ok(())
}

fn function2() -> IoResult<()> {
    // --snip--
    Ok(())
}

在第二个use语句中,我们为std::io::Result类型选择了新名称IoResult,它不会与我们纳入范围的std::fmt的结果冲突。

使用pub重新导出名称

当我们用use关键字将一个名字带入作用域时,在新作用域中可用的名字是私有的。为了使调用我们的代码的代码能够引用该名称,就好像它已经在该代码的作用域中定义了一样,我们可以将pub和use结合起来。这种技术被称为重新导出,因为我们将一个项目纳入范围,但同时也让其他人可以将该项目纳入他们的范围。

下例中将根模块中的use改为了pub use。

文件名:src/lib.rs

mod front_of_house {
    pub mod hosting {
        pub fn add_to_waitlist() {}
    }
}

pub use crate::front_of_house::hosting;          // pub use

pub fn eat_at_restaurant() {
    hosting::add_to_waitlist();
}

在此更改之前,外部代码必须使用路径restaurant::front _ of _ house::hosting::add_to_waitlist()调用add _ to _ wait list函数。既然这个pub use已经从根模块中重新导出了主机模块,那么外部代码现在可以使用路径restaurant::hosting::add _ to _ wait list()来代替。

当您的代码的内部结构与调用您的代码的程序员考虑领域的方式不同时,重新导出是有用的。例如,在这个餐馆的比喻中,经营餐馆的人会想到“房子的前面”和“房子的后面”但是光顾餐馆的顾客可能不会用这些术语来考虑餐馆的各个部分。通过pub use,我们可以用一种结构编写代码,但公开不同的结构。这样做使得我们的库对于在库上工作的程序员和调用库的程序员来说组织得很好。

使用外部包

在之前的章节中,我们编写了一个猜谜游戏项目,它使用一个名为rand的外部包来获得随机数。为了在我们的项目中使用rand,我们将这一行添加到Cargo.toml:

文件名:Cargo.toml

rand = "0.8.3"

在Cargo.toml中添加rand作为依赖项,告诉Cargo从crates.io下载rand包和任何依赖项,并使rand可用于我们的项目。 

然后,为了将rand定义纳入我们的包的范围,我们添加了一个use行,以箱crate的名称rand开始,并列出我们想要纳入范围的项目。如下例:

use std::io;
use rand::Rng;        // use rand库中的Rng

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1..=100);

    println!("The secret number is: {secret_number}");

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {guess}");
}

Rust社区的成员在crates.io上提供了许多包,将它们放入您的包涉及到相同的步骤:在您的包的Cargo.toml文件中列出它们,并使用use将项目从它们的crates放入范围。

注意,标准的std库也是我们包外部的一个crate。因为Rust语言附带了标准库,所以我们不需要修改Cargo.toml来包含std。但是我们确实需要用use来引用它,以便将项目从那里带入我们的包的范围。例如,对于HashMap,我们可以使用下面这行代码:

use std::collections::HashMap;

这是一个以std开始的绝对路径,即标准库箱的名称。

使用嵌套路径

如果我们在同一个crate或者同一个模块中定义了多个项目,那么在单独的一行中列出每个项目会占用我们文件中大量的垂直空间。例如,我们在之前章节的的猜谜游戏中使用的两个use语句将项目从std带入范围:

文件名:src/main.rs

use rand::Rng;              // rand库
// --snip--
use std::cmp::Ordering;     // 标准库
use std::io;                // 标准库
// --snip--

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1..=100);

    println!("The secret number is: {secret_number}");

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    println!("You guessed: {guess}");

    match guess.cmp(&secret_number) {
        Ordering::Less => println!("Too small!"),
        Ordering::Greater => println!("Too big!"),
        Ordering::Equal => println!("You win!"),
    }
}

相反,我们可以使用嵌套路径将相同的项目放在一行中。为此,我们指定路径的公共部分,后跟两个冒号,然后用花括号括起不同路径部分的列表,

use rand::Rng;
// --snip--
use std::{cmp::Ordering, io};     // 嵌套方式
// --snip--

fn main() {
    println!("Guess the number!");

    let secret_number = rand::thread_rng().gen_range(1..=100);

    println!("The secret number is: {secret_number}");

    println!("Please input your guess.");

    let mut guess = String::new();

    io::stdin()
        .read_line(&mut guess)
        .expect("Failed to read line");

    let guess: u32 = guess.trim().parse().expect("Please type a number!");

    println!("You guessed: {guess}");

    match guess.cmp(&secret_number) {
        Ordering::Less => println!("Too small!"),
        Ordering::Greater => println!("Too big!"),
        Ordering::Equal => println!("You win!"),
    }
}

在更大的程序中,使用嵌套路径从同一个板条箱或模块中引入许多项可以减少大量需要的单独use语句的数量!

我们可以在路径中的任何级别使用嵌套路径,这在组合共享子路径的两个use语句时非常有用。例如,下例中显示了两条use语句:一条将std::io引入作用域,另一条将std::io::Write引入作用域。

文件名:src/lib.rs

use std::io;
use std::io::Write;   // std::io下的包

这两条路径的共同部分是std::io,这是完整的第一条路径。要将这两条路径合并成一条use语句,我们可以在嵌套路径中使用self,如下例所示:

文件名:src/lib.rs

use std::io::{self, Write};   // self

这一行将std::io和std::io::Write引入范围。

通配运算符

如果我们希望将路径中定义的所有公共项都纳入范围,我们可以指定该路径后跟* 运算符:

use std::collections::*;   // *通配符

这里的use语句将std::collections中定义的所有公共项都纳入当前范围。使用通配运算符时要小心!通配运算符使得区分什么名字在作用域内以及程序中使用的名字是在哪里定义的变得更加困难。

通配运算符通常在测试时使用,用于将所有被测内容放入测试模块。

本章重点

  • use关键字以及使用方法
  • as关键字以及使用方法
  • pub和use同时使用
  • 引用外部包
  • 嵌套路径使用方法
  • 通配运算符
大数据最新【Rust指南】use关键字妙用 模块内容拆分_rust use //这里并不能使用some_fun()函数,是报错内容。//依然是最后一行可替换前两行。//前两行可用最后一行替代。//打印结果:{1,2} 阅读详情

相关推荐

【Rust指南】use关键字妙用|模块内容拆分

书接上文,本篇补充rust 组织管理中模块的细节知识,比如模块拆分。此外介绍use关键字的习惯用法,快速引用自定义模块内容或标准库,以此优化代码书写。

叶落秋白的博客 5万+

Rust use of undeclared crate or module和maybe a missing crate?

对于新手Ruster来说,最绝望的就是crate找不到了,use of undeclared crate or module和maybe a missing crate? use of undeclared crate or module 在workspace方式组织的项目中,遇到了 error[E0433]: failed to resolve: use of undeclared crate or module db_schema –> main/src/main.rs:2:9 | 2 |

kakadiablo的专栏 1万+

【Rust模块管理】Rust包、crate与模块管理

包:Cargo的一个功能,允许构建,测试,和分享crate。 crate:一个模块的树形结构,形成库或二进制项目。 模块:通过use来使用,用来控制作用域和路径的私有性。 路径:一个命名 例如结构体、函数或模块等项的方式 在 Rust 中,模块(module)是组织代码的基础单位,它帮助你将代码划分为多个逻辑部分,便于管理、复用和控制访问权限。 模块是一个命名空间,用于组织函数、结构体、枚举、常量、trait 和其他模块。Rust 中的模块可以嵌套,并且支持私有和公开访问控制。

景天科技苑 4万+

Rust入门问题: use of undeclared crate or module `rand`

运行程序找不到库,或者叫依赖(rust里有crates, package, module,看字面理解吧)这里0.8.5是指版本,跟你的rust的版本有关。按照官网学rust,程序地址在这里,rand="0.8.5" ,如下,

tanmx219的博客 2900

【Rust指南】组织管理|路径表示|访问权限

为了方便大家学习掌握Rust 语言的语法和概念,因此我将带来一篇Rust 组织管理的内容。任何一门编程语言如果不能组织代码都是难以深入的,几乎没有一个软件产品是由一个源文件编译而成的。包、箱、模块。对于一个软件工程来说,我们往往按照所使用的编程语言的组织规范来进行组织,组织模块的主要结构往往是树。Java 组织功能模块的主要单位是类,而 JavaScript 组织模块的主要方式是function。这些先进的语言的组织单位可以层层包含,就像文件系统的目录结构一样。Rust 中的组织单位是模块...

叶落秋白的博客 2468

评分卡建模学习(一)————数据预处理part.3

目录六、数据处理的思路及代码(一)对缺失值的处理:在我这个数据预处理的part.1板块(二)对异常值的处理:在我这个数据预处理的part.2板块(三)数据归一化、标准化:在我这个数据预处理的part.2板块(四)非结构化数据转变+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++———————————————————————————————————————————++++++++++++++++++++++++++

Morven_dai的博客 898

Rust组织管理,箱Crate包Package和模块module定义和区别,use关键字作用

这里有两个 govern 函数,一个是 nation 下的,一个是 government 下的,我们用 as 将 nation 下的取别名 nation_govern。使用过 Java 的开发者在编程时往往非常讨厌最外层的 class 块——它的名字与文件名一模一样,因为它就表示文件容器,尽管它很繁琐但我们不得不写一遍来强调"这个类是文件所包含的类"。Rust 中的组织单位是模块(Module)。所有的系统库模块都是被默认导入的,所以在使用的时候只需要使用 use 关键字简化路径就可以方便的使用了。

1562

波分复用-Zblock仿真

Z-BLOCK是一种用于光通信模块的光学元件,其核心结构是在玻璃块一侧贴有4个特定波长滤光片,另一侧镀有反射膜和增透膜。光信号在内部呈现Z字形反射路径,实现波长分离。文章以可见光LED为例,在ZEMAX中演示了非序列模式下的建模过程,重点介绍了滤光片和膜层的参数设置方法。需要注意的是,入射角度需根据玻璃折射率、通道高度和厚度精确计算,否则可能导致光泄漏。该建模方法同样适用于光通信中的光纤激光器系统。

Zhaxibamao的博客 1743

Rust从0到1实战系列篇 Rust引用标准库、use 关键字、Rust访问权限、Rust 组织管理

本文介绍了Rust语言中代码组织管理的三个核心概念:箱(Crate)、包(Package)和模块(Module)。箱是二进制或库文件的基本单位,包通过Cargo.toml文件管理工程,模块则用于结构化组织代码。重点讲解了模块的访问控制机制(pub/private关键字)、路径引用方式(绝对/相对路径)、use关键字的导入功能以及标准库的使用方法。通过示例说明了如何在多文件项目中组织模块结构,确保代码的清晰性和可维护性。这些概念共同构成了Rust强大的模块化编程体系。

m0_68635815的博客 988

带挂牵引车前向运动模型推导及仿真实现

牵引车-半挂车的车辆结构与普通的车辆相比增加了一个半挂车,它们之间通过鞍座相连接,为了分析半挂牵引车运动过程中的位姿和状态,本文将基于车辆的机械结构建立对应的运动学模型,该模型基于以下假设: 车辆行驶过程中,道路平坦且无凸凹; 车辆低速行驶,且运行过程中车身无侧倾和俯仰运动; 车辆行驶过程中,轮胎无形变,无侧向滑动,且无侧向力; 牵引车和半挂车均满足阿克曼转向几何原理; 牵引车与半挂车不会发现折叠。

jianmo的博客 3181

python:实现brutefore破解wifi(附完整源码)

python:实现brutefore破解wifi(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 5704

30天拿下Rust之箱、包和模块

Rust语言使用模块系统来组织工程和代码。模块系统允许我们将相关的函数、类型、常量等组织在一起,形成一个逻辑上的单元。通过模块系统,我们可以隐藏实现细节,只暴露必要的接口,从而提高代码的可读性和可维护性。Rust的模块系统还支持路径依赖和重导出等功能,使得代码的组织更加灵活和方便。Rust的模块系统中有三个非常重要的概念,分别是:箱(Crate)、包(Package)和模块(Module),下面逐一进行介绍。

hope_wisdom的技术博客 2123

Win11 1 月更新黑屏循环故障技术分析与解决方案

2026年1月30日Windows 11更新引发黑屏循环故障,主要影响2018年前出厂、采用MBR分区及特定BIOS固件的设备,尤其对使用经典版Outlook(POP协议)的用户影响显著。故障表现为系统无限重启黑屏,导致数据访问中断。分析表明,问题源于硬件兼容性、分区格式与系统更新的交互冲突。解决方案包括进入安全模式回滚更新、暂停自动更新、升级驱动/BIOS,以及等待微软官方补丁。建议用户更新前评估硬件兼容性并备份数据,企业环境应建立分阶段更新测试机制。该事件为系统更新风险管理提供了重要参考。

博客 1441

Rust 组织管理

任何一门编程语言如果不能组织代码都是难以深入的,几乎没有一个软件产品是由一个源文件编译而成的。本教程到目前为止所有的程序都是在一个文件中编写的,主要是为了方便学习 Rust 语言的语法和概念。对于一个工程来讲,组织代码是十分重要的。Rust 中有三个重要的组织概念:箱、包、模块。

m0_65541699的博客 1875

YOLOv5_DeepSORT_Pytorch训练自己的多目标跟踪模型

1 准备 环境配置:https://blog.youkuaiyun.com/weixin_50008473/article/details/115250986?spm=1001.2014.3001.5501 YOLOv5_DeepSORT_Pytorch代码地址: https://github.com/mikel-brostrom/Yolov5_DeepSort_Pytorch DeepSORT论文:https://arxiv.org/pdf/1703.07402.pdf 2 训练目标检测模型 训练自己的目标检测模

weixin_50008473的博客 1万+

通信原理 | CRC循环冗余校验码(最简介明了的原理和matlab程序)

异或运算: 多项式: CRC校验中用到的除数,是由多项式的各项系数组成的,如下所示: 没有的项系数为0,比如:x5次方、x3次方下一步,在原数据串的末端加“0”0的数量由多项式决定具体来说,多项式的阶数是多少就加几个0 具体操作: 现在,我们有了除数,也有了处理过的数据串,如下所示: 就可以开始计算校验和 了将数据串第一个1与除数左对齐,按位进行异或操作: 将未处理的数据搬下来作为新的数据,重复操作: 将新的数据串第一个1与除数左对齐,再重复按位异或操作: 如此循环,直到所有数据都处理过

若北辰 2357

通过包和模块来组织Rust项目

Rust是一种现代的系统编程语言,具有高效性、安全性和并发性等特点。它的构建系统和包管理系统通过Cargo工具提供支持,帮助开发者管理项目、工作空间、包和模块。下面详细介绍Rust中的相关概念及其用法。

yang1fei2的博客 1623

apple游客下单逆向分析

Apple游客下单Cookies注册激活流程逆向分析与算法实现

吴秋霖的博客 1999

使用包、Crate 和模块管理项目(下)

如果希望将一个路径下所有公有项引入作用域,可以指定路径后跟这个use语句将中定义的所有公有项引入当前作用域。使用 glob 运算符时请多加小心!Glob 会使得我们难以推导作用域中有什么名称和它们是在何处定义的。

专注于大数据方向,区块链,前后端,数据可视化,人工智能等领域 2754

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

趣味学RUST基础篇(管理包和模块)

概念类比作用mod建房间划分代码区域路径门牌号定位某个函数或结构体pub开门按钮决定是否对外开放use快捷方式简化对常用项的调用模块树大楼平面图展示所有模块的层级关系。

编码浪子的专栏 951

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Rust语言进阶之关键字:mod用法实例(十六)

本篇目的:Rust语言进阶之关键字:mod用法实例在Rust语言中,mod是一个用于定义模块的关键字。模块是Rust中的一个重要概念,它允许开发者将代码组织成多个逻辑独立的部分。通过模块化,Rust可以将复杂的程序分解成多个较小的部分,从而提高代码的可维护性和可读性。mod关键字不仅用于定义模块,还涉及模块的可见性、结构和作用范围管理。模块系统是Rust中组织和封装代码的基础,为代码提供了层次化的结构,避免了命名冲突,并支持隐式封装和显式公开。mod关键字的主要作用是定义模块。

Android系统攻城狮 1668

visio安装包

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

Rust语言进阶之关键字:use用法实例(十八)

本篇目的:Rust语言进阶之关键字:use用法实例在Rust语言中,use是一个关键字,用于将外部模块、函数、结构体、枚举或常量引入当前作用域。通过use关键字,开发者可以方便地访问其他模块或crate中的公共项,从而简化代码的书写并增强代码的可读性。use是Rust模块系统的重要组成部分,能够让代码跨模块或跨crate进行交互,并有效地管理模块之间的依赖关系。《Android系统多媒体进阶实战》Audio工程师进阶系列多媒体系统工程师系列AAOS车载系统+AOSP14系统攻城狮入门视频实战课。

Android系统攻城狮 1333

Rust之包,箱和模块管理(五):将模块分成不同的文件

Rust之包,箱和模块管理(五):将模块分成不同的文件

wing的专栏 1723

Rust之包,箱和模块管理(二):定义控制范围和隐私的模块

Rust中的定义控制范围和隐私的模块

wing的专栏 573
上一篇: Rust之包,箱和模块管理(三):引用模块树中项目的路径
下一篇: Rust之包,箱和模块管理(五):将模块分成不同的文件
枫★曦
博客等级 码龄19年 251粉丝 153原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值