Rust_2025:阶段1:day7.1 类型转换

as

rust 复制代码
fn average(values: &[f64]) -> f64 {
    let total = values.iter().sum::<f64>();
    total / values.len() as f64
}
  1. 只有一些标准库的特定类型可以用as
  2. 可能会丢失精度,因为会截断

From

rust 复制代码
impl From<&str> for Person {
    fn from(s: &str) -> Person {
        let parts = s.split(',').collect::<Vec <&str>>();
        if parts.len() != 2 {
            return Self::default();
        }
        if parts[0] == "" {
            return Self::default();
        }
        if let Err(_) = parts[1].parse::<usize>(){
            return Self::default();
        }
        Person{ name : parts[0].to_string() , age : parts[1].parse::<usize>().unwrap()}
    }
}
  1. 只能返回Self,无法进行错误处理
  2. 上文如果发现非法字符只能返回默认选项

FromStr

rust 复制代码
impl FromStr for Person {
    type Err = ParsePersonError;
    fn from_str(s: &str) -> Result<Person, Self::Err> {
        if s.len() == 0 {
            return Err(ParsePersonError::Empty);
        }
        let parts = s.split(',').collect::<Vec <&str>>();
        if parts.len() != 2 {
            return Err(ParsePersonError::BadLen);
        }
        if parts[0] == "" {
            return Err(ParsePersonError::NoName);
        }
        if let Err(x) = parts[1].parse::<usize>(){
            return Err(ParsePersonError::ParseInt(x));
        }
        Ok(Person{ name : parts[0].to_string() , age : parts[1].parse::<usize>().unwrap()})
    }
}
  1. 特指字符串转换为其它类型
  2. 实现后可以调用parse< T >()方法,用于将字符串转换为指定类型

TryFrom

rust 复制代码
impl TryFrom<(i16, i16, i16)> for Color {
    type Error = IntoColorError;
    fn try_from(tuple: (i16, i16, i16)) -> Result<Self, Self::Error> {
        if tuple.0 > 255 || tuple.0 < 0 || tuple.1 > 255 || tuple.1 < 1 || tuple.2 > 255 || tuple.2 < 1{
            return Err(Self::Error::IntConversion);
        }
        Ok(Self{red : tuple.0 as u8, green : tuple.1 as u8, blue : tuple.2 as u8})
    }
}

// Array implementation
impl TryFrom<[i16; 3]> for Color {
    type Error = IntoColorError;
    fn try_from(arr: [i16; 3]) -> Result<Self, Self::Error> {
        let mut p = 0;
        for x in arr.iter() {
            if *x > 255 || *x < 1{
                return Err(Self::Error::IntConversion);
            }
            p += 1;
        }
        if p != 3 {
            return Err(Self::Error::BadLen);
        }
        Ok(Self{red : arr[0] as u8, green : arr[1] as u8, blue : arr[2] as u8})
    }
}

// Slice implementation
impl TryFrom<&[i16]> for Color {
    type Error = IntoColorError;
    fn try_from(slice: &[i16]) -> Result<Self, Self::Error> {
        if slice.len() != 3 {
            return Err(Self::Error::BadLen);
        }
        for x in slice.iter() {
            if *x > 255 || *x < 1{
                return Err(Self::Error::IntConversion);
            }
        }
        
        Ok(Self{red : slice[0] as u8, green : slice[1] as u8, blue : slice[2] as u8})
    }
}
  1. 相较于from,可以进行错误处理
  2. 相较于FromStr,可以用于其他类型
  3. 注:类型实现中的Error类型是指:在这类方法中,临时增加一个字段用于存储一个枚举值(该枚举值常用于错误处理,即经常被定义为错误枚举型)

AsRef和AsMut

rust 复制代码
fn byte_counter<T : AsRef<str>>(arg: T) -> usize {
    arg.as_ref().as_bytes().len()
}

// Obtain the number of characters (not bytes) in the given argument.
// TODO: Add the AsRef trait appropriately as a trait bound.
fn char_counter<T : AsRef<str>>(arg: T) -> usize {
    arg.as_ref().chars().count()
}

// Squares a number using as_mut().
// TODO: Add the appropriate trait bound.
fn num_sq<T : AsMut<u32>>(arg: &mut T) {
    // TODO: Implement the function body.
    let mut x = arg.as_mut();
    *x *= *x;
}
  1. 两者分别对应两个方法:
  • as_ref,根据特性约束中的泛型,返回对应泛型的不可变引用(第一个函数返回了一个&str)
  • as_mut,返回可变引用。
rust 复制代码
fn foo<T: AsRef<str> + AsRef<[u8]>>(arg: T) {
   let s: &str = arg.as_ref();
   let bytes: &[u8] = arg.as_ref();
   // ...可以同时使用
}
  1. 可以通过明确类型来同时使用多个AsRef
  2. 但特性约束必须要写。
相关推荐
小灰灰搞电子1 小时前
Rust可以取代C++么?
开发语言·c++·rust
百锦再2 小时前
京东云鼎入驻方案解读——通往协同的“高架桥”与“快速路”
android·java·python·rust·django·restful·京东云
异步思考者6 小时前
Rust实战:一个内存消息队列的 Trait 驱动开发
rust
受之以蒙7 小时前
智能目标检测:用 Rust + dora-rs + yolo 构建“机器之眼”
人工智能·笔记·rust
熬了夜的程序员7 小时前
【Rust学习之路】第 0 章:理解 Rust 的核心哲学
开发语言·学习·rust
EniacCheng7 小时前
【RUST】学习笔记-环境搭建
笔记·学习·rust
禅思院8 小时前
在win10上配置 Rust以及修改默认位置问题
开发语言·前端·后端·rust·cargo·mingw64·cargo安装位置
shandianchengzi8 小时前
【记录】Rust|Rust开发相关的7个VSCode插件的介绍和推荐指数(2025年)
开发语言·vscode·rust
JPX-NO8 小时前
Rust + Rocket + Diesel构建的RESTful API示例(CRUD)
开发语言·rust·restful
林太白9 小时前
Rust01-认识安装
开发语言·后端·rust