如何从闭包中修改闭包之外的值?

时间:2017-11-10 23:20:37

标签: rust

我试图更改dateTimeTravel的值。评论表明我想要的是什么价值,但这不是我得到的。

use std::cell::Cell;

#[derive(Debug, Clone)]
pub struct TimeTravel {
    pub date: Cell<i32>,
}

impl TimeTravel {
    pub fn new() -> Self {
        TimeTravel { date: Cell::new(1) }
    }

    pub fn forward(&self) -> &Self {
        let d = self.date.get();
        self.date.set(d + 1);
        self
    }
}

fn main() {
    let travel: TimeTravel = TimeTravel::new();
    println!("{:?}", travel); // 1
    travel.forward();
    println!("{:?}", travel); // 2

    {
        let t1 = travel.clone();
        let first = || {
            t1.forward();
            println!("{:?}", t1); // 3
            t1.forward();
            println!("{:?}", t1); // 4
        };
        first();
    }

    {
        let t2 = travel.clone();
        let second = || {
            t2.forward();
            println!("{:?}", t2); //5
        };
        second();
    }
}

但是我得到了这个

TimeTravel { date: Cell { value: 1 } }
TimeTravel { date: Cell { value: 2 } }
TimeTravel { date: Cell { value: 3 } }
TimeTravel { date: Cell { value: 4 } }
TimeTravel { date: Cell { value: 3 } }

如果我理解正在发生的事情,我会更改t1t2中的值,而不是travel。如何在闭包内更改travel的值?

Example in Rust Playground

1 个答案:

答案 0 :(得分:1)

我强烈建议您返回并重新阅读 The Rust Programming Language ,第二版,specifically the chapter on ownership。之后,查看Clone的文档,强调我的:

  

明确复制对象的能力的常见特征。

当您致电.clone()时,您将创建该对象的新副本,与原始对象完全不同。对克隆的任何更改都不适用于原始文件。

如评论中所述,您需要删除对t1t2的所有引用,并将其替换为travel

{
    let first = || {
        travel.forward();
        println!("{:?}", travel); // 3
        travel.forward();
        println!("{:?}", travel); // 4
    };
    first();
}

{
    let second = || {
        travel.forward();
        println!("{:?}", travel); //5
    };
    second();
}