我稍微摆弄一下,Any
并进行铸造,以更深入地了解Rust。从C#开始,我习惯于强制转换会导致运行时异常,因为在C#中强制转换基本上意味着Dear编译器,请相信我,我知道我在做什么,请将其强制转换为一个,int32
因为我知道它将可以使用。
但是,如果您执行的是无效的转换,则程序将在运行时爆炸并带有Exception异常。所以我想知道(安全)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;
}
}
到目前为止,我的观察是,编译器似乎阻止了我这种运行时异常,因为我必须强制执行downcast_ref
return,Option
从而使它再次安全。当然,我可以unwrap
在None
将其炸毁,但是这不是我的观点;)
编译器阻止我编写程序let z = v[1] as i32;
,这可能会导致运行时错误。因此,假设以安全的Rust进行转换永远不会导致运行时错误是否正确?
我知道防止运行时错误正是Rust的全部目的,所以这很有意义,我只想验证我的观察:)
使用as
Rust进行铸造非常有限。它仅允许在原始数字和字符类型之间进行转换,在指针和引用之间进行转换,以及根据具体类型的值创建特征对象,仅此而已-as
例如,不可重载。因此,强制转换withas
始终免于惊慌,尽管如果您强制转换无法用目标类型表示的值,则可能会观察到数值溢出,这可能是理想的,也可能是不理想的。
在Rust中,没有C#或Java中的强制转换运算符。最接近std::mem::transmute()
它的是reinterpret_cast
与C ++类似的东西。它unsafe
然而,即使它有它的局限性-它只能变换具有相同大小类型的值。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句