我正在摆弄一点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;
}
}
到目前为止,我的观察是编译器似乎阻止了我这种运行时异常,因为我必须通过强制转换downcast_ref
它返回一个Option
这使它再次安全。我当然可以unwrap
on a None
炸毁它,但这不是我的意思;)
编译器阻止我写let z = v[1] as i32;
这可能会导致运行时错误。那么,假设安全 Rust 中的转换永远不会导致运行时错误是否正确?
我知道防止运行时错误正是 Rust 的全部内容,所以它非常有意义,我只是想验证我的观察:)
铸造用as
Rust 中的功能非常有限。它只允许在原始数字和字符类型之间、指针和引用之间进行转换,以及从具体类型的值创建特征对象,仅此而已 -as
例如,不可过载。因此,铸造用as
总是不会出现恐慌,尽管如果您正在转换无法在目标类型中表示的值,您可能会观察到数字溢出,这可能是理想的,也可能不是理想的。
Rust 中不存在 C# 或 Java 中的强制转换运算符之类的东西。最接近它的是std::mem::transmute()
这很像reinterpret_cast
来自 C++。这是unsafe
然而,即使它也有其局限性——它只能转换具有相同大小的类型的值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)