7. rust类型转换与迭代器详解

一、前言

上一篇文章中,介绍了rust中强大的trait,因此本文就来使用一下这些常用的、且需要自己手动实现的trait来完成一些功能,也就是类型转换与迭代器。

首先我们从较为复杂的类型转换讲起。

rust相比于C/C++,最让人惊艳的便是它的自动类型推导,比如当你写下面这条语句时:

let a=10;

rust编译器将能够自动推导出a的类型为i32,因为字面量10的值就是i32。

当然,这个特性在C/C++中可以使用auto关键字实现,包括本文要介绍的类型转换,C/C++同样也可以实现、甚至可能更加方便(比如强制转换?)。

但rust能够通过人为指定返回值类型来推断函数返回值类型在C/C++中却是无法实现的(也就是本文要介绍的功能)。

包括rust提供了安全性保证、其类型相当直观、即使是枚举类型也能实现方法进行任意类型转换,加上其简练优雅的语法,在体验上C/C++真的很难与之相比。

二、基本理解

类型转换在我的感知中,最实用的一个功能其实是枚举类型:

enum Test {
    One,
    Two,
    Three,
}

比如上面这个枚举类型,当我们想要将其作为字符串输出时,一般可能就得这样做:

fn main() {
    let v = Test::One;
    let str = match v {
        Test::One => "One",
        Test::Two => "Two",
        Test::Three => "Three",
    };
    println!("{}", str);
}

这样做当然是可以的,只不过不够简练优雅。

这样的用途是很多的,比如你想要将其枚举类型值存入数据库中,你无法直接输入枚举类型,必须要先将其转化为字符串。

所以我们还可以将其封装为一个函数进行调用:

fn main() {
    let v = Test::One;
    let str = to_str(v);
    println!("{}", str);
}

fn to_str(v: Test) -> &'static str {
    match v {
        Test::One => "One",
        Test::Two => "Two",
        Test::Three => "Three",
    }
}

这样简练了不少,但仍然不够优雅,因为这个to_str函数现在已经固定只能让Test类型作为参数使用了,但这个函数名却是一个比较常见的名字。

如果放在外面,别的类型也想要使用这个函数名怎么办呢?就会导致重名问题。

所以还能继续改进:

impl Test {
    pub fn to_str(&self) -> &'static str {
        match self {
            Test::One => "One",
            Test::Two => "Two",
            Test::Three => "Three",
        }
    }
}

fn main() {
    let v = Test::One;
    let str = v.to_str();
    println!("{}", str);
}

此时就很直观了,就是调用枚举变量v上的to_str函数,将其转换为字符串。

更进一步,如果我想将其转换为数字类型,那么可能还需要写上这样一个函数:

impl Test {
    pub fn to_str(&self) -> &'static str {
        match self {
            Test::One => "One",
            Test::Two => "Two",
            Test::Three => "Three",
        }
    }

    pub fn to_num(&self) -> i32 {
        match self {
            Test::One => 1,
            Test::Two => 2,
            Test::Three => 3,
        }
    }
}

这种情况是很常见的,我们常常需要将一个类型转化为多种数据类型。

这样做虽然可以,但在调用的时候可能就不太优雅了:

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux