当我需要调用很多失败的函数时,我有时会把它们放在闭包中。 然后我
?
它们并捕获任何特殊变体(其他语言的异常机制)。
以下是我对https://www.codewars.com/kata/5a090c4e697598d0b9000004/train/rust的解决方案
use std::collections::VecDeque;
fn solve(nums: &[i32]) -> Vec<i32> {
let mut sorted = VecDeque::from_iter(nums.iter().copied());
sorted.make_contiguous().sort();
let mut rearranged = vec![];
while let Some(()) =
(||->Option<()>{
rearranged.push(sorted.pop_back()?);
rearranged.push(sorted.pop_front()?);
Some(())
})()
{}
rearranged
}
工作正常而且很干净,但我想知道,
“Rust 是否会在每个while
循环
迭代中产生一个闭包实例”? (编辑:我添加了instance这个词) 如果是这样,它是否检测到产生的闭包是第一个闭包的“重复” 并优化重复?
如果能对闭包在循环内定义的情况进行一些理论上的考虑,我将不胜感激,就像上面那样。编译器做了哪些优化来避免数据重复?
最简单的检查方法是查看生成的程序集,当然是使用
--release
。
您的代码:
solve:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $200, %rsp
movq %rdi, %r8
testq %rdx, %rdx
je .LBB6_6
movq %rdx, %rbx
movq %r8, 128(%rsp)
xorl %ebp, %ebp
movq %rdx, %rax
shrq $61, %rax
sete %al
jne .LBB6_128
movq %rsi, %r14
leaq (,%rbx,4), %rdi
movb %al, %bpl
shlq $2, %rbp
movq %rdi, 104(%rsp)
movq %rbp, %rsi
callq *__rust_alloc@GOTPCREL(%rip)
testq %rax, %rax
je .LBB6_129
movq %rbx, 40(%rsp)
leaq (%r14,%rbx,4), %r12
addq $-4, %r12
movq %r12, %rbp
subq %r14, %rbp
movq %rbp, %rbx
shrq $2, %rbx
leaq 4(%rbp), %rdx
andq $-4, %rdx
movq %rax, (%rsp)
movq %rax, %rdi
movq %r14, %rsi
callq *memcpy@GOTPCREL(%rip)
leaq 1(%rbx), %rax
movq %rax, 16(%rsp)
cmpq $80, %rbp
jae .LBB6_7
movl $1, %r15d
cmpq %r14, %r12
movq (%rsp), %r12
je .LBB6_106
movq 16(%rsp), %rax
leaq (%r12,%rax,4), %r8
addq $-4, %r8
leaq (%r12,%rbx,4), %rcx
addq $4, %rcx
movq $-2, %rbp
jmp .LBB6_97
在变量中定义闭包(playground):
solve:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $200, %rsp
movq %rdi, %r8
testq %rdx, %rdx
je .LBB6_6
movq %rdx, %rbx
movq %r8, 128(%rsp)
xorl %ebp, %ebp
movq %rdx, %rax
shrq $61, %rax
sete %al
jne .LBB6_128
movq %rsi, %r14
leaq (,%rbx,4), %rdi
movb %al, %bpl
shlq $2, %rbp
movq %rdi, 104(%rsp)
movq %rbp, %rsi
callq *__rust_alloc@GOTPCREL(%rip)
testq %rax, %rax
je .LBB6_129
movq %rbx, 40(%rsp)
leaq (%r14,%rbx,4), %r12
addq $-4, %r12
movq %r12, %rbp
subq %r14, %rbp
movq %rbp, %rbx
shrq $2, %rbx
leaq 4(%rbp), %rdx
andq $-4, %rdx
movq %rax, (%rsp)
movq %rax, %rdi
movq %r14, %rsi
callq *memcpy@GOTPCREL(%rip)
leaq 1(%rbx), %rax
movq %rax, 16(%rsp)
cmpq $80, %rbp
jae .LBB6_7
movl $1, %r15d
cmpq %r14, %r12
movq (%rsp), %r12
je .LBB6_106
movq 16(%rsp), %rax
leaq (%r12,%rax,4), %r8
addq $-4, %r8
leaq (%r12,%rbx,4), %rcx
addq $4, %rcx
movq $-2, %rbp
jmp .LBB6_97
它们是相同的。
没有。这是不可能的,因为这意味着在运行时动态生成代码。闭包的定义忽略了控制流。