Rust中的函数指针使用约束泛型 [英] Function pointers in Rust using constrained generics

查看:638
本文介绍了Rust中的函数指针使用约束泛型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  struct MediaLibrary< B> 
其中
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用于其许多文件和路径方法,但我不确定如何添加

我为的几个方法impl '为 MediaLibrary 已经在使用 P:AsRef< Path> 作为参数,所以我的直觉告诉我会有冲突。 $ b

解决方案

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



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

  struct MediaLibrary< F,P1,K,P2,B> 
其中
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,
}



 错误[E0392]:参数`P1`永远不会被使用
- > src / main.rs:3:24
|
3 | struct MediaLibrary< F,P1,K,P2,B>
| ^^未使用的类型参数
|
= help:考虑删除`P1`或使用诸如`std :: marker :: PhantomData`这样的标记

相反,您可以选择仅将约束应用于所使用的函数:

  struct MediaLibrary< f是氟烃基; {
media_item_filter:F,
}

impl< F> MediaLibrary< f是氟烃基; {
fn do_filter< P>(&self)
其中
F:Fn(P) - > bool,
P:AsRef< Path> ;,
{}
}

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


I'm trying to create a struct that looks like this:

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,
}

The last two fields are meant to be used as a predicate to test if a given path is a valid media file and to sort a vector of paths (using sort_by_key), respectively.

However, as it is right now, the design is inflexible: both functions are fixed to accept only Path. I'd like to be able to use P: AsRef<Path> as the stdlib uses for many of its file and path methods, but I'm not sure how to add this.

A number of the methods I've impl'd for MediaLibrary are already using P: AsRef<Path> for their arguments, so my gut feeling tells me that there would be conflicts.

解决方案

To my knowledge, you cannot have a function pointer with a generic type, I don't even think such a construct is accepted by the Rust parser.

Furthermore, you cannot simply switch to extra type parameters on the struct as they would be unused by the struct itself:

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`

Instead, you can choose to apply the constraints only on the functions where they are used:

struct MediaLibrary<F> {
    media_item_filter: F,
}

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

As the message states, you could also use PhantomData.

这篇关于Rust中的函数指针使用约束泛型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆