使用安全Rust进行转换是否会导致运行时错误? [英] Can casting in safe Rust ever lead to a runtime error?
问题描述
我对 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屋!