莆田建设网站建站,保定建网站公司,宣城市住房和城乡建设局网站,wordpress注册导航Rust 类型转换语法大全
Rust 提供了多种类型转换机制#xff0c;以下是详细的分类和语法#xff1a;
1. 隐式转换 (类型强制转换, Coercions)
Rust 只在特定情况下进行隐式类型转换#xff1a;
// 解引用强制多态 (Deref Coercion)
let s: str String::from(以下是详细的分类和语法1. 隐式转换 (类型强制转换, Coercions)Rust 只在特定情况下进行隐式类型转换// 解引用强制多态 (Deref Coercion)lets:strString::from(hello);// 数组/切片指针转换letarr:[i32;3][1,2,3];letslice:[i32]arr;// 函数项到函数指针fnfoo(){}letf:fn()foo;// 生存期延长lets:staticstrhello;lets_ref:strs;2. 显式转换2.1as运算符基本类型转换// 数值类型转换letx:i3242;lety:f64xasf64;// i32 - f64letz:u8xasu8;// i32 - u8// 指针类型转换letptr:*consti32xas*consti32;letmut_ptr:*muti32mutxas*muti32;// 引用到原始指针letref_x:i32x;letraw_ptr:*consti32ref_xas*consti32;// 枚举到整数enumColor{Red0xff0000,Green0x00ff00}letcolor_valColor::Redasu32;// 字符到整数letc:charA;letcode:u32casu32;2.2From和Intotrait安全的类型转换usestd::convert::{From,Into};// From: 从其他类型创建自身structNumber{value:i32,}implFromi32forNumber{fnfrom(item:i32)-Self{Number{value:item}}}letnumNumber::from(30);letnum:Number30.into();// Into 会自动实现// TryFrom/TryInto可能失败的转换usestd::convert::{TryFrom,TryInto};implTryFromi32forNumber{typeErrorString;fntry_from(value:i32)-ResultSelf,Self::Error{ifvalue0{Ok(Number{value})}else{Err(值不能为负数.to_string())}}}letresult:ResultNumber,_5.try_into();3. 类型推断和标注3.1 使用::(turbofish) 语法// 泛型函数类型推断letx42.parse::i32().unwrap();letvecVec::i32::with_capacity(10);// 指定迭代器类型letnums:Veci32vec![1,2,3];letsquaresnums.iter().map(|x|x*x).collect::Vec_();3.2 类型标注letx:i3242;// 变量标注lety42u8;// 字面量后缀letz0xff_u32;// 带下划线的字面量// 函数返回值标注fnget_number()-i32{42}4. 智能指针转换4.1Dereftraitusestd::ops::Deref;structMyBoxT(T);implTDerefforMyBoxT{typeTargetT;fnderef(self)-Self::Target{self.0}}letmy_boxMyBox(5);letx:i32*my_box;// 解引用转换4.2Box,Rc,Arc转换usestd::rc::Rc;usestd::sync::Arc;letboxedBox::new(5);letrcRc::new(5);letarcArc::new(5);// 类型转换letvalue:i32*boxed;letcloned_rc:Rci32rc.clone();5. 字符串转换// str 和 String 互转lets_str:strhello;lets_string:Strings_str.to_string();// 或 String::from(s_str)letback_str:strs_string;// 字节数组转换letbytes:[u8]s_str.as_bytes();letstr_from_bytesstd::str::from_utf8(bytes).unwrap();// 字符迭代器letchars:Vecchars_str.chars().collect();letfrom_chars:Stringchars.into_iter().collect();// 格式化转换letformattedformat!(数字: {},42);letint_from_str:i3242.parse().unwrap();6. 自定义转换 trait6.1AsRef和AsMutfnprint_bytesT:AsRef[u8](data:T){letbytesdata.as_ref();// 处理字节}print_bytes(hello);// str 实现了 AsRef[u8]print_bytes(vec![1,2,3]);// Vecu8 实现了 AsRef[u8]// AsMut 示例fnmodifyT:AsMut[i32](mutdata:T){letslicedata.as_mut();slice[0]42;}6.2Borrow和BorrowMutusestd::borrow::Borrow;fncheckT:Borrowstr(s:T){letborrowed:strs.borrow();// 使用 borrowed}check(hello);check(String::from(world));7. 模式匹配中的类型转换enumMessage{Text(String),Number(i32),}letmsgMessage::Number(42);matchmsg{Message::Text(s)println!(文本: {},s),Message::Number(n)ifn0println!(正数: {},n),Message::Number(n)println!(数字: {},n),}// if let 语法ifletMessage::Number(x0..100)msg{println!(0-100之间的数字: {},x);}8. 高级类型转换技巧8.1 使用transmute不安全usestd::mem;// 必须在 unsafe 块中使用unsafe{letx:i3242;lety:f32mem::transmute(x);// 重新解释字节// 指针类型转换letptr:*consti32x;letptr_usize:usizemem::transmute(ptr);}8.2 使用union进行类型双关unionIntOrFloat{i:i32,f:f32,}letmutuIntOrFloat{i:42};unsafe{println!(整数: {},u.i);u.f3.14;println!(浮点数: {},u.f);}9. 关联类型和泛型约束traitProcessor{typeInput;typeOutput;fnprocess(self,input:Self::Input)-Self::Output;}structStringProcessor;implProcessorforStringProcessor{typeInputString;typeOutputusize;fnprocess(self,input:String)-usize{input.len()}}// 使用泛型约束进行转换fnconvertT,U(value:T)-UwhereT:IntoU,{value.into()}10. 常见的转换习惯用法// Option/Result 转换letopt:Optioni32Some(42);letres:Resulti32,()opt.ok_or(());// 迭代器转换letvecvec![1,2,3];letdoubled:Veci32vec.iter().map(|x|x*2).collect();// 闭包类型转换letadd_one|x:i32|-i32{x1};letfn_ptr:fn(i32)-i32add_one;// 切片转换letarr[1,2,3,4,5];letslice:[i32]arr[1..4];// [2, 3, 4]// 元组转换lettuple(1,hello,3.14);let(a,b,c)tuple;// 解构最佳实践建议优先使用安全的转换From/Intoastransmute利用类型推断尽可能让编译器推断类型显式优于隐式在可能混淆的地方明确标注类型处理转换失败使用TryFrom/TryInto处理可能失败的转换注意性能了解不同转换的成本如String到str是零成本选择哪种转换方式取决于具体场景简单数值转换as自定义类型转换实现From/Into可能失败的转换TryFrom/TryInto引用类型转换AsRef/AsMut不安全的底层转换transmute谨慎使用