Rust中为何return语句报错,返回表达式却正常?
为什么在lazy_static闭包的块中使用显式return会报错?
我有两段几乎一致的lazy_static代码,一段能正常运行,另一段仅因添加了显式return就触发报错,想明确背后的原因。
正常运行的代码:
lazy_static! { static ref TSS: TaskStateSegment = { let mut tss = TaskStateSegment::new(); tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = { const STACK_SIZE: usize = 4096 * 5; static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE]; let stack_start = VirtAddr::from_ptr(unsafe {&STACK}); let stack_end = stack_start + STACK_SIZE; stack_end }; tss }; }
报错的代码:
lazy_static! { static ref TSS: TaskStateSegment = { let mut tss = TaskStateSegment::new(); tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = { const STACK_SIZE: usize = 4096 * 5; static mut STACK: [u8; STACK_SIZE] = [0; STACK_SIZE]; let stack_start = VirtAddr::from_ptr(unsafe {&STACK}); let stack_end = stack_start + STACK_SIZE; return stack_end }; tss }; }
核心原因
问题出在Rust中块表达式的隐式返回规则和显式return的作用域:
- 第一段代码里,赋值语句右侧的
{}是一个块表达式,Rust规定块的返回值默认是块内最后一个表达式的结果(这里就是stack_end),所以这个块会返回VirtAddr类型的值,完美匹配tss.interrupt_stack_table字段的类型;整个闭包最后返回tss,也符合TaskStateSegment的类型要求。 - 第二段代码中的
return stack_end,并不是从赋值右侧的块返回,而是直接从整个lazy_static闭包函数返回。这个闭包要求返回TaskStateSegment类型,但你返回的是VirtAddr,类型完全不匹配;同时return会直接终止闭包执行,后面的tss语句根本不会被执行,这就是Rust Analyzer报错的直接原因。
解决办法
如果你习惯用显式方式表达返回逻辑,不需要用return——保持块的最后一行是你要返回的表达式,就是Rust中最标准的显式表达块返回值的方式。如果一定要用类似“显式返回”的写法,可以给块加上标签并配合return,但这完全没必要,反而会让代码冗余:
// 仅演示标签用法,不推荐实际使用 tss.interrupt_stack_table[DOUBLE_FAULT_IST_INDEX as usize] = 'block: { // ... 其他代码 return 'block stack_end; };
内容的提问来源于stack exchange,提问作者Thetrue kingofwaffles
相关产品推荐
相关产品推荐

