储存C++;向量中的函数? 这是我试图实现的C++等价: std::vector funcs; 函数emplace_back([](int n)->int{return n+1;}); int result=funcs[0](33);

储存C++;向量中的函数? 这是我试图实现的C++等价: std::vector funcs; 函数emplace_back([](int n)->int{return n+1;}); int result=funcs[0](33);,vector,lambda,rust,closures,Vector,Lambda,Rust,Closures,如何用Rust编写上面的代码?如果您不打算将函数移动到任何特定位置,您可以让类型推断在代码块内为您完成工作,并严格定义闭包,就像它是一个普通变量一样(实际上,它是-它实现Fn或FnMut): 如果要将此lambda移出堆栈,则需要将其装箱: let my_lambda: Box<dyn Fn(u32) -> u32> = Box::new(|n| n + 1); println!("{}", my_lambda(33)); 如果它们有完全不同的签名,您将需要编写自己的结构来

如何用Rust编写上面的代码?

如果您不打算将函数移动到任何特定位置,您可以让类型推断在代码块内为您完成工作,并严格定义闭包,就像它是一个普通变量一样(实际上,它是-它实现
Fn
FnMut
):

如果要将此lambda移出堆栈,则需要将其装箱:

let my_lambda: Box<dyn Fn(u32) -> u32> = Box::new(|n| n + 1);
println!("{}", my_lambda(33));
如果它们有完全不同的签名,您将需要编写自己的结构来包含它们,并通过签名将它们存储起来,这不是一项简单的任务


基准案例:

  • C++:

    #包括
    #包括
    #包括
    int main(int argc,字符**argv){
    std::向量函数;
    对于(int i=0;i<10000000;i++){
    函数push_back([&](int n){return n+1;});
    int result=funcs[i](33);
    }
    }
    
  • 锈蚀:

    fn main() {
       let mut lambdas:Vec<Box<Fn(u32) -> u32>> = vec![];
       for i in 0..10000000 {
         lambdas.push(Box::new(|i| i+1));
         lambdas[i](3);
       }
    }
    
  • 最大堆大小:

    --------------------------------------------------------------------------------
    n次(i)总计(B)有用堆(B)额外堆(B)堆栈(B)
    --------------------------------------------------------------------------------
    46    210,486,321      268,440,920      268,436,765         4,155            0
    47    210,486,371      268,440,976      268,436,805         4,171            0
    48    210,486,496      268,441,064      268,436,885         4,179            0
    
结论如下:

  • C++
    std::function
    wrappers是堆分配的。它包含的原始lambda本身是堆栈分配的,这种行为与Rust一致
  • Rust更擅长内存优化,消耗了C堆大小的三分之一++
  • 生锈的速度也比未加工时间快

如果我理解正确, Box 将在堆上分配每个lambda,因此这里有堆上分配的向量,并且每个元素也被分配在堆上,与C++不同,在那里,lambdas不是堆分配的(只是向量本身)。是吗?比这复杂一点。
Vec
本身在堆栈上;其指向内容的内部指针位于堆上;lambda本身也在堆上(毕竟它们是
Vec
的元素)。是的,我理解这一点。我的意思是C++版本似乎更有效,因为它只做1个分配:向量内容。Rust版本实际上分配了指针向量,然后再次分配堆中的每个lambda,将指针存储在向量中。我就是这么看的。我很确定你对
std::function
存储在堆栈上的看法是错误的。除了小对象优化,它们也在堆上。也就是说,损坏函数并不是衡量性能的好方法,因为在Cube和Crand两个引擎下面都有两个优化层。“但是你需要把它们装箱”——这一般不是真的。如果闭包没有捕获任何局部变量,可以将它们强制为函数指针,您可以将它们直接存储在向量中:
let v:Vec i32>=Vec![n | n+1,| n | n-1]
let my_vector: Vec<Box<dyn Fn(u16) -> u16>> = vec![
    Box::new(|i| i + 1),
    Box::new(|i| i - 1),
];
println!("{}", my_vector[0](33))
fn main() {
   let mut lambdas:Vec<Box<Fn(u32) -> u32>> = vec![];
   for i in 0..10000000 {
     lambdas.push(Box::new(|i| i+1));
     lambdas[i](3);
   }
}