Rust 指定函数调用的参数生存期持续
我有一个函数的特性,它引用迭代器:Rust 指定函数调用的参数生存期持续,rust,lifetime,Rust,Lifetime,我有一个函数的特性,它引用迭代器: #[derive(Clone)] struct Dog { name: &'static str, } trait DogListAction<'a, I> where I: Iterator<Item = &'a Dog>, { fn on_dog_list(&mut self, dog_list: I); } struct DogListActionExample {} impl
#[derive(Clone)]
struct Dog {
name: &'static str,
}
trait DogListAction<'a, I>
where
I: Iterator<Item = &'a Dog>,
{
fn on_dog_list(&mut self, dog_list: I);
}
struct DogListActionExample {}
impl<'a, I> DogListAction<'a, I> for DogListActionExample
where
I: Iterator<Item = &'a Dog>,
{
fn on_dog_list(&mut self, dog_list: I) {
for dog in dog_list {
println!("{}", dog.name);
}
}
}
fn main() {
let dogs = vec![Dog { name: "Pluto" }, Dog { name: "Lilly" }];
let mut action_example = DogListActionExample {};
let mut dog_list_actions: Vec<Box<DogListAction<_>>> = vec![Box::new(action_example)];
loop {
let dog_clone = dogs.clone();
for dog_list_action in &mut dog_list_actions {
dog_list_action.on_dog_list(dog_clone.iter());
}
}
}
我猜借用检查器认为,
dog\u clone
中的数据可能会在函数结束后被引用,但事实并非如此。这里的问题是,代码可能会保存对寿命较长的dog\u list\u actions
中的dog\u clone
元素的短期引用。我们需要告诉编译器,我们不会保存迭代器生成的引用。可以这样做:
trait DogListAction {
fn on_dog_list<'a, I>(&'a mut self, dog_list: I)
where
I: Iterator<Item = &'a Dog>;
}
注意框中的第二个'a
。Rust在默认情况下添加了一个绑定到盒装trait对象的'static
trait,我们不希望在这里使用'static
#[derive(Clone)]
struct Dog {
name: &'static str,
}
trait DogListAction {
fn on_dog_list<'a>(&'a mut self, dog_list: Box<dyn Iterator<Item = &'a Dog> + 'a>);
}
struct DogListActionExample {}
impl DogListAction for DogListActionExample {
fn on_dog_list<'a>(&'a mut self, dog_list: Box<dyn Iterator<Item = &'a Dog> + 'a>) {
for dog in dog_list {
println!("{}", dog.name);
}
}
}
fn main() {
let dogs = vec![Dog { name: "Pluto" }, Dog { name: "Lilly" }];
let action_example = DogListActionExample {};
let mut dog_list_actions: Vec<Box<DogListAction>> = vec![Box::new(action_example)];
{
let dogs_clone = dogs.clone();
for dog_list_action in &mut dog_list_actions {
dog_list_action.on_dog_list(Box::new(dogs_clone.iter()));
}
}
}
#[派生(克隆)]
结构狗{
名称:&'static str,
}
特质独断行为{
fn on_dog_list能否请您提供一个,最好是一个游乐场链接?我看不出您显示的代码有任何错误。(有关更多信息,请参阅。)这里是一个链接,指向操场上的一个最小示例:我仍然认为问题在于编译器认为DogListAction可能会引用迭代器中的数据,即使在调用函数之后也是如此。我正在尝试添加显式的生存期规范,但没有成功far@Clynamen,这里的主要问题是代码c在长寿命的dog\u list\u actions
元素中可能保存对dog\u clone
元素的短期引用。如果将dog\u clone.iter()
替换为dogs.iter()
,则代码将编译。您需要在\u dog\u list()上对函数进行签名
表达您不保存迭代器生成的引用的意图。
#[derive(Clone)]
struct Dog {
name: &'static str,
}
trait DogListAction {
fn on_dog_list<'a>(&'a mut self, dog_list: Box<dyn Iterator<Item = &'a Dog> + 'a>);
}
struct DogListActionExample {}
impl DogListAction for DogListActionExample {
fn on_dog_list<'a>(&'a mut self, dog_list: Box<dyn Iterator<Item = &'a Dog> + 'a>) {
for dog in dog_list {
println!("{}", dog.name);
}
}
}
fn main() {
let dogs = vec![Dog { name: "Pluto" }, Dog { name: "Lilly" }];
let action_example = DogListActionExample {};
let mut dog_list_actions: Vec<Box<DogListAction>> = vec![Box::new(action_example)];
{
let dogs_clone = dogs.clone();
for dog_list_action in &mut dog_list_actions {
dog_list_action.on_dog_list(Box::new(dogs_clone.iter()));
}
}
}