使用约束泛型的Rust中的函数指针

时间:2017-11-17 22:47:05

标签: generics rust

我正在尝试创建一个如下所示的结构:

struct MediaLibrary<B>
where
    B: Ord,
{
    root_dir: PathBuf,
    item_meta_fn: String,
    self_meta_fn: String,
    media_item_filter: fn(&Path) -> bool,
    media_item_sort_key: fn(&Path) -> B,
}

最后两个字段用作谓词,用于测试给定路径是否为有效媒体文件,以及分别对路径向量进行排序(使用sort_by_key)。

然而,就像现在一样,设计是不灵活的:两个功能都被固定为只接受Path。我希望能够使用P: AsRef<Path>作为stdlib用于其许多文件和路径方法,但我不确定如何添加它。

implMediaLibrary提供的一些方法已经使用P: AsRef<Path>作为参数,所以我的直觉告诉我会有冲突。

1 个答案:

答案 0 :(得分:3)

据我所知,你不能拥有泛型类型的函数指针,我甚至认为Rust解析器不接受这样的构造。

此外,您不能简单地在结构上切换到额外的类型参数,因为结构本身不会使用它们:

struct MediaLibrary<F, P1, K, P2, B>
where
    F: Fn(P1) -> bool,
    P1: AsRef<Path>,
    K: Fn(P2) -> B,
    P2: AsRef<Path>,
    B: Ord,
{
    root_dir: PathBuf,
    item_meta_fn: String,
    self_meta_fn: String,
    media_item_filter: F,
    media_item_sort_key: K,
}
error[E0392]: parameter `P1` is never used
 --> src/main.rs:3:24
  |
3 | struct MediaLibrary<F, P1, K, P2, B>
  |                        ^^ unused type parameter
  |
  = help: consider removing `P1` or using a marker such as `std::marker::PhantomData`

相反,您可以选择仅对使用它们的函数应用约束:

struct MediaLibrary<F> {
    media_item_filter: F,
}

impl<F> MediaLibrary<F> {
    fn do_filter<P>(&self)
    where
        F: Fn(P) -> bool,
        P: AsRef<Path>,
    {}
}

如消息所述,您还可以使用PhantomData