如何让Rust函数传播状态?

如何让Rust函数传播状态?,rust,Rust,我需要编写一个Rust函数,它可以修改在更高的函数中定义的状态,并在迭代器中将其从一个函数调用传播到另一个函数调用(请参见下面的伪代码) 在坏C中,我会使用一个共享指针。当然,我明白为什么我不应该这样做,为什么我不能在生锈的地方这样做 我找到的解决方法是添加一个额外的函数参数和一个额外的返回参数: fn f(inputs ..., s) { let mut s = s; // computations that rely on the value of s // ...

我需要编写一个Rust函数,它可以修改在更高的函数中定义的状态,并在迭代器中将其从一个函数调用传播到另一个函数调用(请参见下面的伪代码)

在坏C中,我会使用一个共享指针。当然,我明白为什么我不应该这样做,为什么我不能在生锈的地方这样做

我找到的解决方法是添加一个额外的函数参数和一个额外的返回参数:

fn f(inputs ..., s) {
    let mut s = s;
    // computations that rely on the value of s
    // ...
    outputs ..., s
}

fn main() {
    let mut s;
    for ... {
        let (outputs ..., x) = f(inputs ..., s);
        s = x;
    }
}

就编程风格而言,这似乎有点重,我希望有一个更轻的结构(可能更单体),我想象使用闭包。我不知道该怎么写。答案在于参考文献

C中的共享指针附带了关于何时何地可以这样做以及何时不可以这样做的警告。Rust有一个借阅检查器,确保你没有用指针做任何愚蠢/不安全的事情,以防止人们在C中遇到的大部分问题

例如,考虑一下代码的微小变化(纯粹是这样编译的)。可以将其改写如下:

fn do_with(s: &mut u8, item: u8) {
    *s = *s + item;
}
fn main() {
    let mut s: u8 = 0;
    (1..10).for_each(|item| do_with(&mut s, item));
    println!("{}", s)
}
您可以从C中识别出这种语法,但它比C安全得多,因为借阅检查器确保您的代码在任何给定时间都只有一个可变引用。因此,代码在每一步都被认为是正常的,并且可以编译

您也可以像以前那样,通过有效地在调用之间蹦跳值。然而,这确实会导致可读性较差的代码和更高级别的间接寻址。示例如下:

fn do_with(s: u8, item: u8) -> u8 {
    s + item
}
fn main() {
    let mut s: u8 = 0;
    (1..10).for_each(|item| s = do_with(s, item));
    println!("{}", s)
}

在C语言中,指针的危险主要在于对指针的维护和维护。由于生锈会检查并强制执行这一点(而且这会积极地防止你在使用
期货时射中自己的脚),因此这基本上不是问题。

答案在于参考资料

C中的共享指针附带了关于何时何地可以这样做以及何时不可以这样做的警告。Rust有一个借阅检查器,确保你没有用指针做任何愚蠢/不安全的事情,以防止人们在C中遇到的大部分问题

例如,考虑一下代码的微小变化(纯粹是这样编译的)。可以将其改写如下:

fn do_with(s: &mut u8, item: u8) {
    *s = *s + item;
}
fn main() {
    let mut s: u8 = 0;
    (1..10).for_each(|item| do_with(&mut s, item));
    println!("{}", s)
}
您可以从C中识别出这种语法,但它比C安全得多,因为借阅检查器确保您的代码在任何给定时间都只有一个可变引用。因此,代码在每一步都被认为是正常的,并且可以编译

您也可以像以前那样,通过有效地在调用之间蹦跳值。然而,这确实会导致可读性较差的代码和更高级别的间接寻址。示例如下:

fn do_with(s: u8, item: u8) -> u8 {
    s + item
}
fn main() {
    let mut s: u8 = 0;
    (1..10).for_each(|item| s = do_with(s, item));
    println!("{}", s)
}

在C语言中,指针的危险主要在于对指针的维护和维护。由于锈蚀检查和强制执行这一点(并且这一点——积极地——防止您在使用
期货时射中自己的脚),这基本上不是问题。

我什么都不懂,请尝试更准确地说,您想要通过函数返回多个值吗?我同意stargateur,你能澄清一下这个问题吗。如果您想返回一些值并在下一次迭代中使用该值,您可以像这样查看折叠的用法。当然,我理解为什么我不应该这样做,为什么我不能在Rust中这样做。-请与我们分享为什么您“不应该”这样做是如此明显,并提供表明您“不能”这样做的代码。在我的帖子中可能不清楚的是,函数的输入和输出可以依赖于for循环中的IOs,但s的情况并非如此:它只是在函数调用之间共享一个可变值!塞巴斯蒂安·雷诺德的第一个回答以一种生疏的方式回答了我的问题,我可能首先想到的是一些功能性更强、有点离题的东西……我什么都不懂,请尽量精确一点,你想通过函数返回多个值吗?我同意stargateur的观点,你能澄清这个问题吗。如果您想返回一些值并在下一次迭代中使用该值,您可以像这样查看折叠的用法。当然,我理解为什么我不应该这样做,为什么我不能在Rust中这样做。-请与我们分享为什么您“不应该”这样做是如此明显,并提供表明您“不能”这样做的代码。在我的帖子中可能不清楚的是,函数的输入和输出可以依赖于for循环中的IOs,但s的情况并非如此:它只是在函数调用之间共享一个可变值!塞巴斯蒂安·雷诺德的第一个回答以一种生疏的方式回答了我的问题,我可能首先想到的是一些更实用、有点离题的东西……我不同意第二个例子是“可读性较差”或“更高层次的间接性”。我确实认为在这种情况下使用
迭代器::for_each
是一个错误。我不同意第二个示例是“可读性较差”或“更高层次的间接性”。我确实认为在这种情况下使用
迭代器::for_each
是一个错误。