Rust Any Part 3: 我们终于有了 Upcasts
文章庆祝了 Rust 1.86 版本中修复的一个重要问题:允许在 `dyn DebugAny` 上使用 `Any` 的方法,实现了 supertraits 的 upcasting。 之前,即使 `DebugAny` 继承自 `Any`,也无法直接调用 `Any` 的方法,例如 `downcast_ref`。 修复后,这种转换现在可以正常工作,解决了编译错误,使得许多旧的 hack 可以退役。 该修复程序已在 beta 渠道中,稳定版本即将发布。
Rust Any Part 3: 终于我们有了 Upcasts
发表于 2025 年 3 月 27 日星期四
三年前,我在这篇博客上分享了 As-Any Hack。这个 hack 是一种在稳定的 Rust 上实现 supertraits 的 upcasting 的方法。为了唤醒你的记忆,我们的目标是实现这样的功能:
#[derive(Debug)]
struct AnyBox(Box<dynDebugAny>);
traitDebugAny: Any+Debug{}
impl<T: Any+Debug+'static>DebugAnyforT{}
问题是什么?即使 DebugAny 继承自 Any,Rust 也不允许你在 dyn DebugAny 上使用 Any 的方法。因此,虽然你可以正常调用 DebugAny 的方法,但尝试使用 Any 中的 downcast_ref (使用 Any 的首要原因) 将会失败:
fn main(){
letany_box=AnyBox(Box::new(42i32));
dbg!(any_box.0.downcast_ref::<i32>());// 编译错误
}
如果我们尝试将其转换为 &dyn Any 会发生什么? 同样是一个编译错误:
fn main(){
letany_box=AnyBox(Box::new(42i32));
letany=&*any_box.0as&dynAny;
dbg!(any.downcast_ref::<i32>());
}
但是有好消息!从 Rust 1.86 开始,这个问题终于被修复了。这个转换现在可以正常工作了:
[src/main.rs:14:5] any.downcast_ref::<i32>() = Some(
42,
)
在撰写本文时,此修复程序已在 beta 渠道中,但稳定版本即将发布。这意味着许多旧的 hack 最终可以退役了。至少在你的 MSRV 提升之后。
非常感谢所有 为此付出努力 使其工作的人!
这篇文章被标记为 rust