所以我有这个功能
fn render_i32(n: &dyn Typeable, echo: &dyn Fn(&String)) {
let x: &i32 = unsafe {transmute(n)};
echo(&x.to_string());
}
它无法编译,因为无法在不同大小的类型之间转换
。
我想要的代码如下:我有一个 HashMap
,其中包含不同类型的渲染函数。每个可能呈现的类型都必须实现我的接口(interface) Typeable
,它基本上只返回该类型的常量 type_id
(我刚刚遇到了一个 type_id
) code> 在 std 中,想知道我是否可以使用它来代替......)。然后使用该 type_id 我可以在我的 HashMap 中查找正确的渲染函数。因此,我的代码确保仅针对 i32
调用 render_i32
。这工作得很好。
现在,所有这些在 C 中都非常容易,我只需将值转换为指针即可。但在使用rust 中,这似乎并不那么容易。我不明白 i32 值。我怎样才能得到它?
编辑:我自己的方法的替代解决方案,类型不安全性较低,但也欢迎解决以下要求:客户(使用此库的)应该能够添加自己的渲染函数他们自己的类型...
请注意,渲染函数不应静态定义一次:同一类型可能会使用不同的渲染函数,具体取决于语言设置等。
最佳答案
我仍然不明白为什么你不使用传统的trait
-impl
方法,它似乎做了你想做的事情,除了函数指针不这样做没有任何通用的数据结构来保存它们(它可能比 HashMap
的方法对缓存不太友好)
use std::iter;
// lib
fn echo_windows(s: &String) {
println!("C:/Users> {}", s)
}
fn echo_linux(s: &String) {
println!("$ {}", s)
}
trait Renderable {
fn render(&self, echo: &dyn Fn(&String));
}
// client
struct ClientType {
ch: char,
len: usize,
}
impl Renderable for ClientType {
fn render(&self, echo: &dyn Fn(&String)) {
let to_echo: String = iter::repeat(self.ch)
.take(self.len)
.collect();
echo(&to_echo);
}
}
fn main() {
ClientType{ ch: '#', len: 5 }.render(&echo_windows); // output: C:/Users> #####
ClientType{ ch: '!', len: 3 }.render(&echo_linux); // output: $ !!!
}
关于rust - 将未知类型转换为已知类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68314483/