你怎么能弄清楚函数的类型签名(参考)?

时间:2015-01-26 16:02:12

标签: rust type-signature

我想测试一些函数的实现。为了干净利落地做,我想将它们的引用放入一个数组中并逐个调用它们。由于最近的语法更改,要执行此操作,您需要首先使用正确的类型签名显式地将函数强制转换为函数引用。由于用于声明函数的语法与其实际类型不同,因此这是一项非常重要的任务。

如何计算出具有非平凡签名的Rust函数的引用类型(例如,它涉及泛型,生命周期,另外的函数等)?

特定的function(我写的)是用签名声明的:

pub fn take_while2<'a,T,F:Fn(&T)->bool >(initial: &'a [T], predicate: F) -> Option<&'a [T]> {...}

1 个答案:

答案 0 :(得分:2)

至少你不能使用这个功能。

首先,你不能拥有通用变量。也就是说,x不能依赖T。举一个更简单的例子:

fn test<T>(_: &T) { unimplemented!() }

fn main() {
    let x: fn(&u8) = test;
}

这是有效的,因为编译器可以推断具体类型T(在本例中为u8)。那你为什么不能那样做呢?因为F。你要求一个闭包类型,闭包类型是匿名;无论你做什么,你都不能说出一个。如果你设法让类型系统推断闭包类型,它只对完全一个特定的闭包有效。与函数非常相似,每个闭包都有自己独特的类型,即使它字面上相同。与函数不同,闭包没有可以使用的公共基类型。

如果不知道你实际想要完成的是什么,很难提出任何建议。然而,要在黑暗中进行刺杀,你可能想尝试类似的东西:

pub fn take_while2<'a,T>(initial: &'a [T], predicate: Box<Fn(&T) -> bool>) -> Option<&'a [T]> { // '
    // ...
}

fn main() {
    let functions: Vec<for<'a> fn(&'a [u8], Box<Fn(&u8) -> bool>) -> Option<&'a [u8]>> = vec![take_while2]; // '
    // ...
}

请注意使用for<'a>这是一个排名较高的生命周期,它与'a定义的take_while2泛型参数具有相同的功能。 另外请注意,此语法 不适用于类型参数。

感谢Shepmaster提醒我您使用&Fn(&T) -> bool而不是盒装关闭。这解除了调用者的堆分配要求。

这还需要您将要传递给predicate的任何闭包。