为何在Result<_, &str>上使用?会引发生命周期错误?
Rust可变借用冲突:&str与String返回类型差异原因
问题代码
impl BytePacketBuffer { fn read(&mut self) -> Result<u8, &str> { if self.pos >= 512 { return Err("End of buffer".into()); } let res = self.buf[self.pos]; self.pos += 1; Ok(res) } fn read_u16(&mut self) -> Result<u16, &str> { let res = ((self.read()? as u16) << 8) | (self.read()? as u16); Ok(res) } }
编译错误信息
error[E0499]: cannot borrow `*self` as mutable more than once at a time --> src/byte_packet_buffer.rs:53:51 | 52 | fn read_u16(&mut self) -> Result<u16, &str> { | - let's call the lifetime of this reference `'1` 53 | let res = ((self.read()? as u16) << 8) | (self.read()? as u16); | ------------ ^^^^^^^^^^^ second mutable borrow occurs here | | | first mutable borrow occurs here | returning this value requires that `*self` is borrowed for `'1`
原因解析
当read方法返回Result<u8, &str>时,Rust会自动推导生命周期:错误类型&str的生命周期会和输入的&mut self绑定,也就是说,read返回的错误引用必须和self的可变借用存活时间一致。
在read_u16的表达式里,连续两次调用self.read()会触发冲突:
- 第一次调用
self.read()时,会获取self的可变借用,由于错误分支的&str和self绑定,这个借用需要一直保持有效,直到整个Result被完全处理(?操作符会在错误时直接返回,Rust必须确保此时引用依然有效)。 - 这就导致第二次调用
self.read()时,self还处于第一次调用的可变借用锁定状态,违反了Rust“同一时间只能存在一个可变借用”的核心规则,因此编译报错。
当把返回类型改为String后,read返回的错误是拥有完全所有权的字符串,不再依赖self的生命周期。此时每次read调用完成后,可变借用会立即释放——Ok分支处理完后,借用就结束了,第二次调用可以正常获取新的可变借用,所以代码能正常编译。
内容的提问来源于stack exchange,提问作者Dowson Jones
相关产品推荐
相关产品推荐

