thread在 Rust 中,handle.join().unwrap()

📅 2026/7/1 7:56:05 👤 编程新知 🏷️ 技术资讯
thread在 Rust 中,handle.join().unwrap() 如果结果是Ok(t)则返回内部的值t如果结果是Err(e)则会触发 panic 并显示错误信息fn main() { // 创建一个线程并获取其句柄 let handle thread::spawn(|| { thread::sleep(Duration::from_secs(1)); 线程执行完成 // 线程的返回值 }); // 等待线程完成并获取返回值 let result handle.join().unwrap(); println!({}, result); // 输出: 线程执行完成 }在 Rust 中let _ handle.join();是一种处理线程 JoinHandle 的方式它的作用是调用join()方法阻塞当前线程等待被 spawn 的线程执行完成使用let _ 忽略join()返回的 Result 值与handle.join().unwrap()不同这种写法会静默忽略任何可能的错误包括线程恐慌。3 安装curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh或者wget --https-only --secure-protocolTLSv1_2 -qO- https://sh.rustup.rs | sh刷新环境变量安装完成后需要让终端识别新安装的rustup命令执行source $HOME/.cargo/env3.1 问题安装rustup时报错[22:35:07] rootceph-221:/home/code/eza# curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh info: downloading installer warn: It looks like you have an existing installation of Rust at: warn: /usr/bin warn: It is recommended that rustup be the primary Rust installation. warn: Otherwise you may have confusion unless you are careful with your PATH. warn: If you are sure that you want both rustup and your already installed Rust warn: then please reply y or yes or set RUSTUP_INIT_SKIP_PATH_CHECK to yes warn: or pass -y to ignore all ignorable checks. error: cannot install while Rust is installed解决方法这个错误是因为系统中已经通过包管理器如apt、yum等安装了 Rust而rustup检测到了现有安装为了避免环境冲突而终止了安装。解决方法如下为了让rustup成为主要的 Rust 工具链管理器建议先卸载系统预装的 Rustsudo dnf remove rust cargo卸载完成后重新运行rustup安装脚本。4 格式化输出在 Rust 中println!({:?}, other);是一个用于打印变量other调试信息的宏调用其中{:?}是格式化占位符对应Debug格式化输出。4.1.1 核心作用{:?}要求被打印的类型实现了标准库的std::fmt::Debugtrait该 trait 用于提供类型的调试友好格式通常包含详细的内部结构。与{}对应Displaytrait不同Debug输出更偏向开发者调试格式可能更冗长例如包含字段名、引号等且通常由编译器自动派生通过#[derive(Debug)]无需手动实现。{:?}的变体{:#?}会生成带缩进的多行格式适合复杂结构如嵌套的结构体、长列表5 所有权在Rust中由Copy trait来区分值语义和引用语义。与此同时Rust也引入了新的语义复制Copy语义和移动Move语义。复制语义对应值语义移动语义对应引用语义。Rust的借用检查器(borrow checker)借用检查器会检查所有数据访问是否合法。借用检查依赖于3个紧密关联的概念所有权、生命周期和借用。所有权(ownership)是一个引申而来的比喻在Rust中所有权与针对不再需要的值的清理有关。值的生命周期是一个时间段在此时间段内对该值的访问是有效的行为。借用一个值意味着要访问它。所有权的特点控制资源不仅仅是内存的释放出借所有权包括不可变共享和可变独占的通过使用操作完成所有权租借在不可变借用期间所有者不能修改资源也不能在进行可变借用在可变借用期间所有者不能访问资源并且也不能再出借所有权不可变借用可以出借多次因为他不能修改内存数据可变借用只能出借一次否则难以预料数据何时何地被修改。转移所有权生命周期参数的目的是帮助借用检查器验证合法的引用消除悬垂指针借用的生命周期不能长于出借方的生命周期结构体实例的生命周期应短于或等于任意一个成员的生命周期省略生命周期参数每个输入位置上省略的生命周期都将成为一个不同的生命周期参数如果只有一个输入生命周期的位置不管是否忽略则该生命周期都将分配给输出生命周期如果存在多个输入生命周期的位置但是其中包含着self或mut self则self的生命周期都将分配给输出生命周期对于BoxT类型来说如果包含的类型T属于复制语义则执行按位复制如果属于移动语义则移动所有权6 类型6.1 ?Sized在 Rust 中?Sized是一个用于 trait bound 的特殊标记用于表示“允许类型不实现Sizedtrait”。要理解它首先需要了解Sizedtrait 本身6.1.1 Sized trait 是什么Sized是 Rust 中的一个自动实现的 trait用于标记“在编译时已知大小的类型”例如i32、String、自定义结构体等。对于这类类型编译器知道它们在内存中占据的精确大小因此可以直接在栈上分配也能作为函数参数/返回值直接传递。反之动态大小类型DSTDynamically Sized Type则不实现Sized例如切片[T]长度未知需通过[T]等指针间接使用trait 对象如dyn Trait具体类型大小未知字符串字面量的底层类型str长度未知需通过str使用。?Sized的作用放宽Sized限制Rust 中泛型默认隐含Sized约束。例如fn fooT(x: T) { ... } // 等价于 fn fooT: Sized(x: T) { ... }这意味着泛型T只能接受编译时大小已知的类型Sized类型。而?Sized的作用是取消这种默认约束允许泛型接受“可能不实现Sized的类型”。例如fn barT: ?Sized(x: T) { ... }这里T可以是Sized类型如i32也可以是动态大小类型如str、dyn Trait。6.1.2 使用场景?Sized通常用于需要处理动态大小类型的场景常见情况接受 trait 对象trait 对象dyn Trait是 DST因此泛型需要?Sized才能接受它trait MyTrait { fn do_something(self); } // 允许 T 为 dyn MyTraitDST fn call_traitT: MyTrait ?Sized(x: T) { x.do_something(); } // 使用可以传入任何实现 MyTrait 的类型的引用或 trait 对象 let obj: dyn MyTrait SomeType; call_trait(obj); // 合法处理切片或字符串直接使用[T]或str时通常通过引用// 接受 strDST的引用 fn print_strT: ?Sized(s: T) where T: AsRefstr { println!({}, s.as_ref()); } print_str(hello); // 字符串字面量是 str底层是 strDST定义容纳 DST 的类型例如自定义智能指针时指向 DSTstruct MyBoxT: ?Sized(*const T); implT: ?Sized MyBoxT { fn new(x: T) - Self { MyBox(x as *const T) } }6.1.3 注意点?Sized仅用于泛型约束不能直接修饰具体类型。由于 DST 无法在栈上直接存储或作为值传递使用?Sized的泛型通常需要通过引用T或指针如BoxT、RcT间接操作。?Sized是“允许不Sized”而非“必须不Sized”因此仍能接受Sized类型。7 logRUST_LOG是 Rust 生态中用于控制日志输出的环境变量主要配合 Rust 的日志库如log、tracing使用用于动态调整日志的级别、模块范围和输出内容无需修改代码即可灵活控制程序的日志行为。log是Rust 生态中最基础、应用最广泛的日志抽象库crate它本身不直接实现日志的输出功能而是定义了一套统一的日志接口如日志级别、宏定义让其他库或应用可以基于这套接口实现日志记录同时保证不同日志实现之间的兼容性提供统一的日志接口定义了trace!、debug!、info!、warn!、error!等日志宏以及Log、Level、Metadata等核心 trait 和枚举让开发者可以用一致的方式编写日志代码无需关心底层如何输出如打印到终端、写入文件、发送到日志服务器等。解耦日志生产与消费库开发者只需依赖log库编写日志如info!(初始化完成)而应用开发者可以自由选择日志的实现方式如env_logger、tracing、fern等两者通过log的接口对接避免了库与特定日志实现的强耦合。