如何从性状本身直接降低 rust 病性状

waxmsbnn  于 2023-02-16  发布在  其他
关注(0)|答案(1)|浏览(174)

在这个问题中:
How to get a reference to a concrete type from a trait object?
解释如何使用Any向下转换Trait。但是我想直接从Trait向下转换到所有支持的已知类型,而不是使用通用的as_any方法。我尝试了:

pub trait A{
    fn as_B(&self) -> B {
        (&self as &dyn Any).downcast_ref::<B>().expect("Can't cast to B").clone()
    }
}
impl A for B{}

但我得到的错误:生存期可能不够长强制转换要求'1必须比'static
我试过:
1.将trait A标记为克隆,但这不是一个选项,因为这会破坏使用A的其他Trait,并需要这些trait成为对象trait。
1.在trait中加入生命周期参数,这会在很多地方使用trait A,最后我会得到同样的编译错误。
1.从self中移除&。但这两个选项都不是,因为A的大小未知。

2lpgd968

2lpgd9681#

编辑:
如果你只想知道Any做了什么,而不想在rust playground中经历它,这是UB,因为Any意味着转换为usable type

trait A{
    // Edited from std::any::Any downcast_ref_unchecked there is a checked version if you want to look
    fn downcast_ref_unchecked(&self) -> &B where Self: Sized{
            // Don't ask me how this works but I believe it dips into C land of pointers
            unsafe { &*(self as *const dyn A as *const B) }
    }
}
// Target
#[derive(Debug)]
struct B;

// Test
#[derive(Debug)]
struct C;

// Have test struct have 'A' trait
impl A for C {}

fn main(){
    let t = C{};
    println!("{:?}", t.downcast_ref_unchecked());
    println!("{:?}", t);
}

相关问题