可以在安全的Rust中进行转换会导致运行时错误吗?

Chr*_*oph 3 casting rust

Any为了更深入地了解Rust,我正在努力摆弄并投入.从C#我习惯了这样一个事实,即转换可能会导致运行时异常,因为在C#中进行转换基本上意味着亲爱的编译器,相信我,我知道我在做什么请将其转换成一个int32因为我知道它会起作用.

但是,如果您正在执行无效的转换,程序将在运行时以异常方式爆炸.所以我想知道(安全)Rust中的转换是否同样会导致运行时异常.

所以,我想出了这个代码来试一试.

use std::any::Any;

fn main() {
    let some_int = 4;
    let some_str = "foo";
    {
      let mut v = Vec::<&Any>::new();
      v.push(&some_int);
      v.push(&some_str);

      // this gives a None
      let x = v[0].downcast_ref::<String>();
      println!("foo {:?}", x);

      //this gives Some(4)
      let y = v[0].downcast_ref::<i32>();
      println!("foo {:?}", y);

      //the compiler doesn't let me do this cast (which would lead to a runtime error)
      //let z = v[1] as i32;

    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止我的观察是编译器似乎阻止了我这种运行时异常,因为我必须通过downcast_ref哪个返回Option使得它再次安全.当然,我可以unwrap用它None来炸毁它,但这不是我的观点;)

编译器阻止我写入let z = v[1] as i32;可能导致运行时错误.那么,假设在安全Rust中进行转换永远不会导致运行时错误,这是正确的吗?

我知道防止运行时错误正是Rust的全部意义所以它非常有意义,我只想验证我的观察结果:)

Vla*_*eev 5

as在Rust中铸造是非常有限的.它只允许在原始数字和字符类型之间,在指针和引用之间进行转换,以及用于从具体类型的值中创建特征对象,并且这就是全部 - as例如,不可重载.因此,as如果您正在投射一个无法在目标类型中表示的值,您可以观察到数字溢出,这可能是恐慌,也可能不是.

在Rust中,没有来自C#或Java的强制转换操作符.最接近std::mem::transmute()它的是reinterpret_cast与C++ 很相似的东西.它unsafe然而,即使它有它的局限性-它只能变换具有相同大小类型的值.