Rust 类型转换语法大全(deepseek)

Rust 类型转换语法大全

Rust 提供了多种类型转换机制,以下是详细的分类和语法:

1. 隐式转换 (类型强制转换, Coercions)

Rust 只在特定情况下进行隐式类型转换:

rust 复制代码
// 解引用强制多态 (Deref Coercion)
let s: &str = &String::from("hello");

// 数组/切片指针转换
let arr: [i32; 3] = [1, 2, 3];
let slice: &[i32] = &arr;

// 函数项到函数指针
fn foo() {}
let f: fn() = foo;

// 生存期延长
let s: &'static str = "hello";
let s_ref: &str = s;

2. 显式转换

2.1 as 运算符(基本类型转换)

rust 复制代码
// 数值类型转换
let x: i32 = 42;
let y: f64 = x as f64;    // i32 -> f64
let z: u8 = x as u8;      // i32 -> u8

// 指针类型转换
let ptr: *const i32 = &x as *const i32;
let mut_ptr: *mut i32 = &mut x as *mut i32;

// 引用到原始指针
let ref_x: &i32 = &x;
let raw_ptr: *const i32 = ref_x as *const i32;

// 枚举到整数
enum Color { Red = 0xff0000, Green = 0x00ff00 }
let color_val = Color::Red as u32;

// 字符到整数
let c: char = 'A';
let code: u32 = c as u32;

2.2 FromInto trait(安全的类型转换)

rust 复制代码
use std::convert::{From, Into};

// From: 从其他类型创建自身
struct Number {
    value: i32,
}

impl From<i32> for Number {
    fn from(item: i32) -> Self {
        Number { value: item }
    }
}

let num = Number::from(30);
let num: Number = 30.into();  // Into 会自动实现

// TryFrom/TryInto(可能失败的转换)
use std::convert::{TryFrom, TryInto};

impl TryFrom<i32> for Number {
    type Error = String;
    
    fn try_from(value: i32) -> Result<Self, Self::Error> {
        if value >= 0 {
            Ok(Number { value })
        } else {
            Err("值不能为负数".to_string())
        }
    }
}

let result: Result<Number, _> = 5.try_into();

3. 类型推断和标注

3.1 使用 ::<> (turbofish) 语法

rust 复制代码
// 泛型函数类型推断
let x = "42".parse::<i32>().unwrap();
let vec = Vec::<i32>::with_capacity(10);

// 指定迭代器类型
let nums: Vec<i32> = vec![1, 2, 3];
let squares = nums.iter().map(|x| x * x).collect::<Vec<_>>();

3.2 类型标注

rust 复制代码
let x: i32 = 42;          // 变量标注
let y = 42u8;            // 字面量后缀
let z = 0xff_u32;        // 带下划线的字面量

// 函数返回值标注
fn get_number() -> i32 { 42 }

4. 智能指针转换

4.1 Deref trait

rust 复制代码
use std::ops::Deref;

struct MyBox<T>(T);

impl<T> Deref for MyBox<T> {
    type Target = T;
    
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

let my_box = MyBox(5);
let x: i32 = *my_box;  // 解引用转换

4.2 Box, Rc, Arc 转换

rust 复制代码
use std::rc::Rc;
use std::sync::Arc;

let boxed = Box::new(5);
let rc = Rc::new(5);
let arc = Arc::new(5);

// 类型转换
let value: i32 = *boxed;
let cloned_rc: Rc<i32> = rc.clone();

5. 字符串转换

rust 复制代码
// &str 和 String 互转
let s_str: &str = "hello";
let s_string: String = s_str.to_string();    // 或 String::from(s_str)
let back_str: &str = &s_string;

// 字节数组转换
let bytes: &[u8] = s_str.as_bytes();
let str_from_bytes = std::str::from_utf8(bytes).unwrap();

// 字符迭代器
let chars: Vec<char> = s_str.chars().collect();
let from_chars: String = chars.into_iter().collect();

// 格式化转换
let formatted = format!("数字: {}", 42);
let int_from_str: i32 = "42".parse().unwrap();

6. 自定义转换 trait

6.1 AsRefAsMut

rust 复制代码
fn print_bytes<T: AsRef<[u8]>>(data: T) {
    let bytes = data.as_ref();
    // 处理字节
}

print_bytes("hello");      // &str 实现了 AsRef<[u8]>
print_bytes(vec![1, 2, 3]); // Vec<u8> 实现了 AsRef<[u8]>

// AsMut 示例
fn modify<T: AsMut<[i32]>>(mut data: T) {
    let slice = data.as_mut();
    slice[0] = 42;
}

6.2 BorrowBorrowMut

rust 复制代码
use std::borrow::Borrow;

fn check<T: Borrow<str>>(s: T) {
    let borrowed: &str = s.borrow();
    // 使用 borrowed
}

check("hello");
check(String::from("world"));

7. 模式匹配中的类型转换

rust 复制代码
enum Message {
    Text(String),
    Number(i32),
}

let msg = Message::Number(42);

match msg {
    Message::Text(s) => println!("文本: {}", s),
    Message::Number(n) if n > 0 => println!("正数: {}", n),
    Message::Number(n) => println!("数字: {}", n),
}

// if let 语法
if let Message::Number(x @ 0..=100) = msg {
    println!("0-100之间的数字: {}", x);
}

8. 高级类型转换技巧

8.1 使用 transmute(不安全)

rust 复制代码
use std::mem;

// 必须在 unsafe 块中使用
unsafe {
    let x: i32 = 42;
    let y: f32 = mem::transmute(x);  // 重新解释字节
    
    // 指针类型转换
    let ptr: *const i32 = &x;
    let ptr_usize: usize = mem::transmute(ptr);
}

8.2 使用 union 进行类型双关

rust 复制代码
union IntOrFloat {
    i: i32,
    f: f32,
}

let mut u = IntOrFloat { i: 42 };
unsafe {
    println!("整数: {}", u.i);
    u.f = 3.14;
    println!("浮点数: {}", u.f);
}

9. 关联类型和泛型约束

rust 复制代码
trait Processor {
    type Input;
    type Output;
    
    fn process(&self, input: Self::Input) -> Self::Output;
}

struct StringProcessor;

impl Processor for StringProcessor {
    type Input = String;
    type Output = usize;
    
    fn process(&self, input: String) -> usize {
        input.len()
    }
}

// 使用泛型约束进行转换
fn convert<T, U>(value: T) -> U
where
    T: Into<U>,
{
    value.into()
}

10. 常见的转换习惯用法

rust 复制代码
// Option/Result 转换
let opt: Option<i32> = Some(42);
let res: Result<i32, ()> = opt.ok_or(());

// 迭代器转换
let vec = vec![1, 2, 3];
let doubled: Vec<i32> = vec.iter().map(|x| x * 2).collect();

// 闭包类型转换
let add_one = |x: i32| -> i32 { x + 1 };
let fn_ptr: fn(i32) -> i32 = add_one;

// 切片转换
let arr = [1, 2, 3, 4, 5];
let slice: &[i32] = &arr[1..4];  // [2, 3, 4]

// 元组转换
let tuple = (1, "hello", 3.14);
let (a, b, c) = tuple;  // 解构

最佳实践建议

  1. 优先使用安全的转换From/Into > as > transmute
  2. 利用类型推断:尽可能让编译器推断类型
  3. 显式优于隐式:在可能混淆的地方明确标注类型
  4. 处理转换失败 :使用 TryFrom/TryInto 处理可能失败的转换
  5. 注意性能 :了解不同转换的成本(如 String&str 是零成本)

选择哪种转换方式取决于具体场景:

  • 简单数值转换:as
  • 自定义类型转换:实现 From/Into
  • 可能失败的转换:TryFrom/TryInto
  • 引用类型转换:AsRef/AsMut
  • 不安全的底层转换:transmute(谨慎使用)
相关推荐
ServBay6 小时前
7个Rust写法让代码干净卫生又高效
后端·rust
Source.Liu8 小时前
【Rust】变量系统详解
rust
Source.Liu10 小时前
【Rust】数组与向量:集合类型全解
rust
唐装鼠10 小时前
Rust Box<T> 和引用(deepseek)
开发语言·rust
Source.Liu10 小时前
【Rust】结构体(Struct)详解
rust
isyuah11 小时前
Miko v0.7 发布:我写的一个 Rust Web 框架,虽然还是个玩具
后端·rust
isyuah12 小时前
Miko 框架系列(十四):集成测试
后端·rust
唐装鼠12 小时前
Rust Turbofish 语法详解(deepseek)
开发语言·后端·rust
Source.Liu12 小时前
【Rust】字符串类型全览:从 UTF-8 到系统路径
rust