gpt4 book ai didi

rust - Sized 没有为 Fn 类型实现

转载 作者:行者123 更新时间:2023-11-29 07:43:02 24 4
gpt4 key购买 nike

我想构建一个将列表分成两部分的函数:一个列表包含满足特定谓词的原始列表的元素,另一个包含所有不满足的元素。以下是我的尝试:

fn split_filter<T: Clone + Sized>(a: &Vec<T>, f: Fn(&T) -> bool) -> (Vec<T>, Vec<T>) {
let i: Vec<T> = vec![];
let e: Vec<T> = vec![];
for u in a.iter().cloned() {
if f(&u) {
i.push(u)
} else {
e.push(u)
}
}

return (i, e);
}

fn main() {
let v = vec![10, 40, 30, 20, 60, 50];
println!("{:?}", split_filter(&v, |&a| a % 3 == 0));
}

但是,我得到两个错误:

error[E0277]: the trait bound `for<'r> std::ops::Fn(&'r T) -> bool + 'static: std::marker::Sized` is not satisfied
--> src/main.rs:1:47
|
1 | fn split_filter<T: Clone + Sized>(a: &Vec<T>, f: Fn(&T) -> bool) -> (Vec<T>, Vec<T>) {
| ^ `for<'r> std::ops::Fn(&'r T) -> bool + 'static` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `for<'r> std::ops::Fn(&'r T) -> bool + 'static`
= note: all local variables must have a statically known size

error[E0308]: mismatched types
--> src/main.rs:17:39
|
17 | println!("{:?}", split_filter(&v, |&a| a % 3 == 0));
| ^^^^^^^^^^^^^^^ expected trait std::ops::Fn, found closure
|
= note: expected type `for<'r> std::ops::Fn(&'r {integer}) -> bool + 'static`
found type `[closure@src/main.rs:17:39: 17:54]`

第二个错误似乎暗示闭包不是 Fn。我尝试使用语法 f: |&T| -> bool 我在网上的某个地方找到的,但这似乎在最新版本的 Rust 中不起作用。

至于第一个错误,我曾希望使 T Sized 能够使函数具有已知的大小,但显然它没有。

最佳答案

你应该阅读 Rust 官方书籍,尤其是 the chapter on closures .您的函数声明不正确;您正在指定 f具有裸特征类型,这是不可能的;这正是关于 Sized 的错误是关于。您应该改用泛型类型参数:

fn split_filter<T: Clone, F>(a: &[T], f: F) -> (Vec<T>, Vec<T>)
where
F: for<'a> Fn(&'a T) -> bool,

我还更改了 a 的类型来自 &Vec<T>&[T] ;在任何情况下您都更喜欢前者而不是后者。 &Vec<T>自动强制为 &[T]必要时。参见 Why is it discouraged to accept a reference to a String (&String) or Vec (&Vec) as a function argument?

第二个错误与函数声明中的错误密切相关;您的原始函数声明指定了一个裸特征类型,但闭包没有这种类型,它们只是实现了函数特征。

最终的程序是这样的:

fn split_filter<T: Clone, F>(a: &[T], f: F) -> (Vec<T>, Vec<T>)
where
F: Fn(&T) -> bool,
{
let mut i: Vec<T> = vec![];
let mut e: Vec<T> = vec![];
for u in a.iter().cloned() {
if f(&u) {
i.push(u);
} else {
e.push(u);
}
}

return (i, e);
}

fn main() {
let v = vec![10, 40, 30, 20, 60, 50];
println!("{:?}", split_filter(&v, |&a| a % 3 == 0));
}

playground 上试试.

关于rust - Sized 没有为 Fn 类型实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32618872/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com