Rust : 关于*const () 与type erase

发布于:2025-04-17 ⋅ 阅读:(82) ⋅ 点赞:(0)

*const () 可以替代泛型,更加灵活。下面举了两个完全不一样的数据结构Foo和Bar;以及不同的函数,来说明。

一、 代码


trait Work {
    fn process(&self);
}
struct Foo(String);

impl Work for Foo {
    fn process(&self) {
        println!("process work  from Foo : {}", self.0);
    }
}
struct Bar{
    code:String,
    open:f64,
    high:f64,
    low:f64,
    close:f64,
}
impl Bar{
    fn new(code:String,open:f64,high:f64,low:f64,close:f64)->Self{
        Self{
            code,
            open,
            high,
            low,
            close,
        }
    }
}
impl Work for Bar {
    fn process(&self) {
        println!("process work  from Bar : {}", self.code);
    }
}
fn fn_foo(foo: &Foo){
    println!("call fn_foo, output ->{}", foo.0);
}
fn fn_bar(bar: &Bar){
    println!("call fn_bar, output ->code:{} open:{} high:{} close:{} low:{},", bar.code,bar.open,bar.high,bar.close,bar.low);
}
fn main() {
    let foo = Foo("foo".into());
    let bar = Bar::new("600036.SH".into(),36.9,37.8,36.7,36.4);
    let unsafe_fn_foo: unsafe fn(*const ()) = fn_const_ptr(fn_foo as fn(&Foo));
    process_method::<Foo>( unsafe_fn_foo,&foo);

    let unsafe_fn_bar: unsafe fn(*const ()) = fn_const_ptr(fn_bar as fn(&Bar));

    process_method::<Bar>(unsafe_fn_bar,&bar);

    let foo_ptr: *const () = data_const_ptr(&foo);
    let bar_ptr: *const () = data_const_ptr(&bar);
    process_data::<Foo>(foo_ptr);
    process_data::<Bar>(bar_ptr);
}

fn process_data<T: Work>(data: *const ()) {
     let obj: *const T = data.cast::<T>();
     unsafe{(*obj).process()};
}
fn process_method<T>(f:  unsafe fn(*const ()),data:&T) {
    let ptr: *const () = data as *const T as _; // 这里"_"type erase
    unsafe{
        f(ptr)
    };
}
fn data_const_ptr<T>(data: &T) -> *const () {
    data as *const T as _ // 这里"_"type erase
}
fn fn_const_ptr<T>(f: fn(&T)) -> unsafe fn(*const ()) {
    unsafe {
        std::mem::transmute(f)
    }
}

二、输出结果

   Compiling type_erase v0.1.0 (D:\my_program\type_erase)
    Finished `release` profile [optimized] target(s) in 2.08s
     Running `target\release\type_erase.exe`
call fn_foo, output ->foo
call fn_bar, output ->code:600036.SH open:36.9 high:37.8 close:36.4 low:36.7,
process work  from Foo : foo
process work  from Bar : 600036.SH



网站公告

今日签到

点亮在社区的每一天
去签到