[英]How to write a function that takes a slice of functions?
I am trying to write a function that takes a slice of functions. 我正在尝试编写一个需要一部分函数的函数。 Consider the following simple illustration :
考虑下面的简单说明 :
fn g<P: Fn(&str) -> usize>(ps: &[P]) { }
fn f1() -> impl Fn(&str) -> usize { |s: &str| s.len() }
fn f2() -> impl Fn(&str) -> usize { |s: &str| s.len() }
fn main() {
g(&[f1(), f2()][..]);
}
It fails to compile: 它无法编译:
error[E0308]: mismatched types
--> src/main.rs:6:15
|
6 | g(&[f1(), f2()][..]);
| ^^^^ expected opaque type, found a different opaque type
|
= note: expected type `impl for<'r> std::ops::Fn<(&'r str,)>` (opaque type)
found type `impl for<'r> std::ops::Fn<(&'r str,)>` (opaque type)
Is there any way to do this? 有什么办法吗?
Your problem is that every element of the array must be of the same type, but the return of a function declared as returning impl Trait
is an opaque type , that is an unspecified, unnamed type, that you can only use by means of the given trait. 您的问题是数组的每个元素必须具有相同的类型,但是声明为returning
impl Trait
的函数的返回是不透明的类型 ,即未指定的,未命名的类型,您只能通过给定的方式使用特征。
You have two functions that return the same impl Trait
but that does not mean that they return the same type. 您有两个函数返回相同的
impl Trait
但这并不意味着它们返回相同的类型。 In fact, as your compiler shows, they are different opaque types, so they cannot be part of the same array. 实际上,如编译器所示,它们是不同的不透明类型,因此它们不能属于同一数组。 If you were to write an array of values of the same type, such as:
如果要编写一个具有相同类型的值的数组,例如:
g(&[f1(), f1(), f1()]);
then it would work. 那就行了。 But with different functions, there will be different types and the array is impossible to build.
但是使用不同的功能,将有不同的类型,并且无法构建数组。
Does that mean there is no solution for your problem? 这是否意味着您的问题没有解决方案? Of course not!
当然不是! You just have to invoke dynamic dispatch.
您只需要调用动态调度即可。 That is you have to make your slice of type
&[&dyn Fn(&str) -> usize]
. 那就是您必须使
&[&dyn Fn(&str) -> usize]
类型的切片。 For that you need to do two things: 为此,您需要做两件事:
&dyn Trait
or Box<dyn Trait>
instead of Trait
). &dyn Trait
或Box<dyn Trait>
而不是Trait
)完成。 &dyn Trait
to avoid ambiguities in the conversion. &dyn Trait
进行显式转换,以避免转换中的歧义。 There are many ways to do the cast: you can cast the first element of the array, or you can declare the temporary variables, or give the slice a type. 有很多方法可以进行转换:可以转换数组的第一个元素,也可以声明临时变量,或为切片指定类型。 I prefer the latter, because it is more symmetric.
我更喜欢后者,因为它更加对称。 Something like this:
像这样:
fn main() {
let fns: &[&dyn Fn(&str) -> usize] =
&[&f1(), &f2()];
g(fns);
}
Link to a playground with this solution. 使用此解决方案链接到游乐场 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.