Casting 安全锈迹中的强制转换是否会导致运行时错误?

Casting 安全锈迹中的强制转换是否会导致运行时错误?,casting,rust,Casting,Rust,我在玩弄Any和铸造,只是为了更深入地了解锈蚀。从C开始,我习惯了这样一个事实,即强制转换可能导致运行时异常,因为在C中强制转换基本上意味着亲爱的编译器,相信我,我知道我在做什么,请将此转换为int32,因为我知道它会工作 但是,如果您正在执行无效的强制转换,程序将在运行时发生异常。所以我想知道,在(安全)锈迹中强制转换是否同样会导致运行时异常 所以,我想出了这个代码来尝试一下 use std::any::Any; fn main() { let some_int = 4; l

我在玩弄
Any
和铸造,只是为了更深入地了解锈蚀。从C开始,我习惯了这样一个事实,即强制转换可能导致运行时异常,因为在C中强制转换基本上意味着亲爱的编译器,相信我,我知道我在做什么,请将此转换为
int32
,因为我知道它会工作

但是,如果您正在执行无效的强制转换,程序将在运行时发生异常。所以我想知道,在(安全)锈迹中强制转换是否同样会导致运行时异常

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

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;

    }
}
使用std::any::any;
fn main(){
让一些_int=4;
让我们来看看;
{
让mut v=Vec:::new();
v、 推送(&some_int);
v、 推送(&some_str);
//这是一个零
设x=v[0]。向下投影参考::();
println!(“foo{:?}”,x);
//这给出了一些(4)
设y=v[0]。向下倾斜的参考::();
println!(“foo{:?}”,y);
//编译器不允许我执行此强制转换(这将导致运行时错误)
//设z=v[1]为i32;
}
}
到目前为止,我的观察结果是,编译器似乎阻止我出现这种运行时异常,因为我必须通过
downcast\u ref
进行转换,这将返回一个
选项,使其再次安全。当然,我可以在
None
unwrap
将其放大,但这不是我的观点;)

编译器阻止我将z=v[1]写为i32可能导致运行时错误。那么,假设在安全锈迹中进行铸造永远不会导致运行时错误,这是正确的吗


我知道防止运行时错误正是Rust的核心所在,因此它非常有意义,我只想验证我的观察:)

在Rust中使用
进行强制转换是非常有限的。它只允许在基元数字和字符类型之间、指针和引用之间以及在具体类型的值之外创建trait对象之间进行强制转换,仅此而已-
,例如,
是不可重载的。因此,使用
as
进行强制转换总是没有死机的,尽管如果您正在强制转换一个无法在目标类型中表示的值,您可以观察到数值溢出,这可能是可取的,也可能是不可取的


在Rust中,没有C#或Java中的cast操作符。最接近的是代码> STD::MEM::TrimueUnter(<代码> >,这与C++中的代码> RealTytCase< /Cuff>非常相似。然而,它是不安全的,甚至它也有其局限性——它只能转换具有相同大小的类型的值。

这取决于您如何定义“运行时错误”和“结果”

正如Vladimir所说的那样,
As
只适用于不能真正失败的原始转换。但目前(Rust 1.3)中存在一个邪恶的小漏洞:

如果您试图强制转换一个没有相应整数值的浮点值,结果是最终得到一个包含“something”的整数。LLVM认为一个奇怪的“东西”不可能存在(当然,在进行转换之前,您检查了转换是否有意义)。编译器根据不可能发生的事情进行优化

最终的结果是,您可以通过使用非常大的值来创建奇怪的未定义整数来崩溃或损坏内存,这些整数在运行时会产生不一致的结果,这可能包括受控和非受控崩溃


我的意思是,它不应该这样做,解决办法可能是让
变成
恐慌,因为当有人要求编译器计算
f32::NAN as i32
时,您还会做什么?

如果无法静态确定
x as i32
强制转换是否有效,则另一个解决方案是发出编译时错误。