gpt4 book ai didi

rust - 为了向下转换一个特征对象,为什么它必须是静态的?

转载 作者:行者123 更新时间:2023-12-03 11:25:02 25 4
gpt4 key购买 nike

std::error::Error trait 正在向新设计过渡。值得注意的是它的 cause方法:

fn cause(&self) -> Option<&dyn Error>

已被弃用并被替换为:

fn source(&self) -> Option<&(dyn Error + 'static)>

除了名称之外,唯一的变化是新方法返回 'static . fix error RFC给出的原因是:

The problem with the existing cause API is that the error it returns is not 'static. This means it is not possible to downcast the error trait object, because downcasting can only be done on 'static trait objects (for soundness reasons).



这对我来说根本不明显。这是为什么?

最佳答案

理解它的最好方法是实现一个!这个问题:

  • How to get a reference to a concrete type from a trait object?

  • 是一个很好的起点。其中的实现依赖于 std::any::Any但没有说明为什么 'static是必须的。如果要直接以与 (dyn Any)::downcast_ref() 相同的方式实现虽然( playground ):

    use std::any::TypeId;

    trait A {
    fn type_id(&self) -> TypeId
    where
    Self: 'static,
    {
    TypeId::of::<Self>()
    }
    }

    impl dyn A + 'static {
    fn is<T: A + 'static>(&self) -> bool {
    let t = TypeId::of::<T>();
    let concrete = self.type_id();

    t == concrete
    }

    fn downcast_ref<T: A + 'static>(&self) -> Option<&T> {
    if self.is::<T>() {
    unsafe { Some(&*(self as *const dyn A as *const T)) }
    } else {
    None
    }
    }
    }

    struct B;

    impl A for B {}

    fn main() {
    let a: Box<dyn A> = Box::new(B);

    let _b: &B = match a.downcast_ref::<B>() {
    Some(b) => b,
    None => panic!("&a isn't a B!"),
    };
    }
    unsafe这里实际上是安全的,因为由于类型 id 检查,我们只是向下转换回原始类型。实现以 TypeId 为中心给我们保证:

    A TypeId is currently only available for types which ascribe to 'static, but this limitation may be removed in the future.



    如果再深入一点,方式 how this type id is calculated at the moment终于给了我们答案。也就是说,一个结构体 Struct<'a>可能有 N 个实例,其中 'a 具有不同的具体替换, 但类型 id 是相同的。是 TypeId向所有人开放 Struct<'a> ,然后我们可以向下转换任何 Struct<'a>Struct<'static> ,这将是一个健全性问题。

    关于rust - 为了向下转换一个特征对象,为什么它必须是静态的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59476994/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com