将未知类型转换为已知类型

约翰·史密斯

所以我有这个功能

fn render_i32(n: &dyn Typeable, echo: &dyn Fn(&String)) {
    let x: &i32 = unsafe {transmute(n)};
    echo(&x.to_string());
}

它无法编译,因为cannot transmute between types of different sizes.

我想要这段代码如下:我有一个HashMap包含不同类型的渲染函数。可能呈现的每种类型都必须实现我的 interface Typeable,它基本上只返回type_id该类型的常量(我刚刚type_id在 std 中遇到了一个,并且想知道我是否可以使用它来代替......)。然后type_id我可以使用它在我的HashMap. 所以我的代码确保,这render_i32仅被调用i32这工作正常。

现在所有这些在 C 中都非常容易,我只需将值转换为指针下的值。但在 Rust 中,它似乎并不那么容易。我不明白 i32 的值。我怎么会得到那个?

编辑:我自己的方法的替代解决方案不那么类型不安全,但也欢迎解决以下要求:客户(使用此库的人)应该能够为自己的类型添加自己的渲染功能......

请注意,渲染函数不应该被静态定义一次:不同的渲染函数可能用于相同的类型,例如取决于语言设置。

罗马卡德纳斯

也许您可以将Anytrait用于您的目的:

use std::any::Any;

pub trait Typeable {
   ...
   fn as_any(&self) -> &dyn Any;
}

fn render_i32(n: &dyn Typeable, echo: &dyn Fn(&String)) {
    let x: &i32 = n.as_any().downcast_ref::<i32>().unwrap();
    echo(&x.to_string());
}

downcast_ref::<i32>()方法返回一个Option<&i32>,因此您还可以检查向下转换是否有效。您甚至可以以通用方式执行此操作:

fn render<T:'static + std::fmt::Display>(n: &dyn Typeable, echo: &dyn Fn(&String)) {
    let x: &T = n.as_any().downcast_ref::<T>().unwrap();
    echo(&x.to_string());
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章