使用安全Rust进行转换是否会导致运行时错误? [英] Can casting in safe Rust ever lead to a runtime error?

查看:45
本文介绍了使用安全Rust进行转换是否会导致运行时错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Any 有点偏爱,并进行了铸造,以更深入地了解Rust.从C#开始,我习惯于强制转换会导致运行时异常,因为在C#中强制转换基本上意味着亲爱的编译器,相信我,我知道我在做什么,请将其强制转换为 int32 ,因为我知道它会起作用.

I'm fiddling a bit with Any and casting just to get a deeper understanding of Rust. From C# I'm used to the fact that casting can lead to runtime exceptions because casting in C# basically means Dear compiler, trust me, I know what I'm doing please cast this into an int32 because I know it will work.

但是,如果您执行的是无效的强制转换,则程序将在运行时爆炸并带有异常.因此,我想知道是否(强制)Rust使用强制转换会同样导致运行时异常.

However, if you're doing an invalid cast the program will blow up with an Exception at runtime. So I was wondering if casting in (safe) Rust can equally lead to a runtime exception.

因此,我想出了这段代码来进行尝试.

So, I came up with this code to try it out.

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;

    }
}

到目前为止,我的观察是编译器似乎阻止了我这种运行时异常,因为我必须强制执行 downcast_ref 并返回 Option ,这使其变得安全.再次.当然,我可以对 None 上的 unwrap 进行炸毁,但这不是我的意思;)

My observation so far is that the compiler seems to prevent me from this kind of runtime exceptions because I have to cast through downcast_ref which returns an Option which makes it safe again. Sure, I can unwrap on a None to blow it up but that's not my point ;)

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

The compiler prevents me from writing let z = v[1] as i32; which could lead to a runtime error. So, is it correct to assume that casting in safe Rust will never result in a runtime error?

我知道防止运行时错误正是Rust的全部目的,因此这很有意义,我只想验证一下观察结果:)

I know that preventing runtime errors is exactly what Rust is all about so it makes perfect sense, I just want to validate my observation :)

推荐答案

在Rust中使用 as 进行铸造非常有限.它仅允许在原始数字和字符类型之间进行转换,在指针和引用之间进行转换,以及根据具体类型的值创建特征对象,仅此而已-例如, as 是不可重载的.因此,使用 as 进行强制转换始终可以避免恐慌,但是如果您强制转换无法用目标类型表示的值,则可能会观察到数值溢出,这可能是不希望的.

Casting with as in Rust is very limited. It only allows casting between primitive numeric and character types, between pointers and references and for creating trait objects out of values of concrete types, and that's all - as is not overloadable, for example. Therefore, casting with as is always panic-free, though you can observe numeric overflows if you're casting a value which can't be represented in the target type, which may or may not be desirable.

在Rust中,没有C#或Java中的强制转换运算符.最接近它的是 std :: mem :: transmute(),它与C ++中的 reinterpret_cast 很像.但是,它是 unsafe ,甚至有其局限性-它只能转换大小相同的类型的值.

In Rust there is no such thing as the cast operator from C# or Java. The closest thing to it would be std::mem::transmute() which is a lot like reinterpret_cast from C++. It is unsafe, however, and even it has its limitations - it can only transform values of types having the same size.

这篇关于使用安全Rust进行转换是否会导致运行时错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆