关于这个问题,将闭包存储在 HashMap 中,我了解到正确地将闭包传递给函数需要该函数是通用的,并且采用任何实现 Fn、FnMut 或 FnOnce 特征的类型。
在实现 C++ 库的一部分作为学习练习时,我需要某种类似这样的类型抽象。
use std::collections::HashMap;
struct Event;
trait IObject {
fn makeFunc<F : FnMut(&Event)>(&mut self, s : &str, f : F);
}
struct Object1<'a> {
m_funcs : HashMap<String, Box<FnMut(&Event) + 'a>>
}
impl <'a> Object1<'a> {
fn new() -> Object1<'a> {
Object1 {m_funcs : HashMap::new()}
}
}
impl <'a> IObject for Object1<'a> {
fn makeFunc<F : FnMut(&Event) + 'a>(&mut self, s: &str, f: F) {
self.m_funcs.insert(String::from_str(s), Box::new(f));
}
}
fn main() {
let obj : &IObject = &Object1::new();
println!("Hello, world!");
}
但是,返回的错误表明 IObject 不能是特征对象,因为它包含具有通用参数的方法。然而,为了将闭包传递给函数,我需要泛型。有人可以告诉我如何实现我正在寻找的抽象,同时仍然能够将闭包传递给函数吗?
你无法回避这个问题;静态和动态调度不能混合。静态分派(泛型)所做的单态化根本无法与动态分派(特征对象)中使用的 vtable 一起使用。
两者之一必须去掉:要么使用IObject
作为特征对象或通用函数参数,有利于接受Box<FnMut(&Event) + 'a>
.
顺便说一下,请注意你的IObject
实现与特征不匹配——特征没有给出生命周期限制F
,您的实现的位置。你需要添加'a
无论如何,作为特征定义的通用(通用寿命对特质对象没问题)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)