我正在尝试获取部分应用的函数的列表,如下所示:
fn partially_applied() -> Vec<Box<dyn Fn(u32) -> u32>> {
let xs = vec![1_u32, 2, 3];
xs.into_iter().map(|x| Box::new(move |y| x + y)).collect()
}
编译器向我产生一个错误:
错误[E0277]:类型std::vec::Vec的值
随后的尝试也没有成功:
1.
fn partially_applied_with_explicit_collect_type() -> Vec<Box<dyn Fn(u32) -> u32>> {
let xs = vec![1_u32, 2, 3];
xs.into_iter().map(|x| Box::new(move |y| x + y)).collect::<Vec<Box<dyn Fn(u32) -> u32>>>()
}
fn partially_applied_with_explicit_vec_type() -> Vec<Box<dyn Fn(u32) -> u32>> {
let xs = vec![1_u32, 2, 3];
let mut res: Vec<Box<dyn Fn(u32) -> u32>> = xs.into_iter().map(|x| Box::new(move |y| x + y)).collect();
res
}
fn partially_applied_with_explicit_push() -> Vec<Box<dyn Fn(u32) -> u32>> {
let xs = vec![1_u32, 2, 3];
let mut res = vec![];
for x in xs {
res.push(Box::new(move |y| x + y));
}
res
}
也只有这一次尝试最终成功了!
fn partially_applied_with_explicit_push_and_vec_type() -> Vec<Box<dyn Fn(u32) -> u32>> {
let xs = vec![1_u32, 2, 3];
let mut res: Vec<Box<dyn Fn(u32) -> u32>> = vec![];
for x in xs {
res.push(Box::new(move |y| x + y));
}
res
}
为什么在动态闭包方面类型推断如此糟糕?
为什么收集
在第一次尝试中不起作用?
有没有更好的方法来利用类型推理来表达这样的想法?
潜在的问题是每个闭包都有它自己的不可命名的类型,它是唯一的成员。此外,编译器可以自动将特定的装箱闭包转换成< code>Box
因此,以下是确定的:
fn closure() -> Box<dyn Fn(u32) -> u32> {
Box::new(|x| x)
}
但这不是:
fn partially_applied() -> Vec<Box<dyn Fn(u32) -> u32>> {
let xs = vec![1_u32, 2, 3];
xs.into_iter().map(|x| Box::new(move |y| x + y)).collect()
}
为什么不呢?
value of type `Vec<Box<dyn Fn(u32) -> u32>>` cannot be built from
`std::iter::Iterator<Item=Box<[closure@src/main.rs:12:37: 12:51]>>`
help: the trait `FromIterator<Box<[closure@src/main.rs:12:37: 12:51]>>`
is not implemented for `Vec<Box<dyn Fn(u32) -> u32>>`
这是因为< code>Vec的< code>FromIterator中绑定的trait是
impl<T> FromIterator<T> for Vec<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vec<T> { ... }
}
和<代码>框
所以问题不在于“为什么 Rust 的类型推断在这里失败了”,而是“为什么 Vec 没有实现以下内容”:
impl<T, U> FromIterator<T> for Vec<U>
where T: Into<U> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Vec<U> { ... }
}
我不知道。我怀疑当存在多对<code>T,U</code>时,这会导致其自身的类型推断问题。
注意:您可以按以下方式将您的盒子转换为正确的类型:
fn partially_applied() -> Vec<Box<dyn Fn(u32) -> u32>> {
let xs = vec![1_u32, 2, 3];
xs.into_iter()
.map(|x| Box::new(move |y| x + y) as Box<dyn Fn(u32) -> u32>)
.collect()
}
在第七章我们粗略介绍了一下Vec的用法。实际上,作为Rust中一个非常重要的数据类型,熟练掌握Vec的用法能大大提升我们在Rust世界中的编码能力。 特性及声明方式 和我们之前接触到的Array不同,Vec具有动态的添加和删除元素的能力,并且能够以O(1)的效率进行随机访问。同时,对其尾部进行push或者pop操作的效率也是平摊O(1)的。 同时,有一个非常重要的特性(虽然我们编程的时候大部分都不
为什么可以推断闭包表达式的参数类型和返回类型,而不是rust中的函数?
我认为以下代码可以工作: 但是我得到了一个编译器错误(见这里):
前面说泛型的时候,提到了C++模板的实现方式是动态特性静态化,在实际情况中,这是一个提高效率的好办法。动态性的好处是灵活,开发简便,静态性的特性是效率高,编译期检查较好,因此很自然地就有一个问题,能不能各取所长,达到两全其美?应该说,在一定程度上是可以的,比如这篇即将讨论的静态类型推导,简称类型推导,因为动态类型无所谓什么推导。个人认为类型推导是编译原理最复杂的东西之一,其他复杂的有垃圾回收,代码
闭包从封闭的作用中域捕获变量简单明了。这样会有某些后果吗?当然会。观察一下使用闭包作为函数参量的方式是要求为泛型的,它们定义的方式决定了这是必要的(原文:Observe how using a closure as a function parameter requires generics, which is necessary because of how they are defined):
问题内容: 在下面函数的第三行,出现以下错误: 无法在当前上下文中推断闭包类型 我该如何解决? 问题答案: 它不推断闭包类型的原因是因为未处理该语句。这意味着关闭预期会出现错误,但是在您的情况下,您忘记了规则。 因此,您可以尝试使用以下答案来捕获您的错误: 然后,您可以断言错误(用于测试),或者我个人会设置警报。 这样,应用程序不会崩溃,而是通知用户。我发现这在旅途中 非常 有用,而且我的设备未插