我正在创建一个具有两个参数的 API 函数,我希望第二个参数的类型取决于第一个参数的值,例如:
enum Component{
Cpu,
Disk
}
struct CpuState {
pub frequency: u64
}
struct DiskState {
pub speed: u64
}
type Handler<T> = Box<dyn Fn(T) -> Box<dyn Future<Output = String> + Send> + Send + Sync>;
// the type of parameter(`<T>`) in handler is depends on the component you chosen.
fn monitor(component: Component, handler: Handler){}
我尝试过的方法是使用特征,但不起作用:
trait StateEventHandler {
type Component;
type Handler;
}
impl StateEventHandler for CpuState {
type Component = Component::Cpu; // error: expected type, found variant `Component::Cpu`
not a type
type Handler = Handler<CpuState>;
}
impl StateEventHandler for DiskState {
type Component = Component::DiskState; // error like above
type Handler = Handler<DiskState>;
}
fn monitor<T: StateEventHandler>(component: T::Component, handler: T::Handler){}
怎么办呢?
Component::Cpu
和Component::Disk
是 的枚举变体Component
,而不是单独的类型。因此,您不能在impl
的上将它们声明为关联类型StateEventHandler
。不允许这样做的广泛原因是,用户传递了哪个特定的枚举变量是仅在运行时才知道的信息,但通用单态化发生在编译时。如何根据运行时信息“设置”编译时类型要求?你不能。
也许你应该只声明两个单元结构,如下所示:
这就是如何表达你需要的语义。
CpuComponent
如果您仍然需要在其他地方使用枚举DiskComponent
,您也可以这样做。std::net::IpAddr
就是一个很好的例子。strum::EnumDiscriminants
也可能会派上用场。