【发布时间】:2020-11-17 16:16:28
【问题描述】:
我为 leetcode same tree problem 编写了这段代码:
use std::cell::RefCell;
use std::rc::Rc;
// Definition for a binary tree node.
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
pub val: i32,
pub left: Option<Rc<RefCell<TreeNode>>>,
pub right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
#[inline]
pub fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None,
}
}
}
struct Solution;
impl Solution {
pub fn is_same_tree(
p: Option<Rc<RefCell<TreeNode>>>,
q: Option<Rc<RefCell<TreeNode>>>,
) -> bool {
match (p, q) {
(None, None) => true,
(Some(p), Some(q)) if p.borrow().val == q.borrow().val => {
// this line won't work, it will cause BorrowMutError at runtime
// but the `a & b` version works
return (Self::is_same_tree(
p.borrow_mut().left.take(),
q.borrow_mut().left.take(),
)) && (Self::is_same_tree(
p.borrow_mut().right.take(),
q.borrow_mut().right.take(),
));
let a = Self::is_same_tree(p.borrow_mut().left.take(), q.borrow_mut().left.take());
let b =
Self::is_same_tree(p.borrow_mut().right.take(), q.borrow_mut().right.take());
a && b
}
_ => false,
}
}
}
fn main() {
let p = Some(Rc::new(RefCell::new(TreeNode {
val: 1,
left: Some(Rc::new(RefCell::new(TreeNode::new(2)))),
right: Some(Rc::new(RefCell::new(TreeNode::new(3)))),
})));
let q = Some(Rc::new(RefCell::new(TreeNode {
val: 1,
left: Some(Rc::new(RefCell::new(TreeNode::new(2)))),
right: Some(Rc::new(RefCell::new(TreeNode::new(3)))),
})));
println!("{:?}", Solution::is_same_tree(p, q));
}
thread 'main' panicked at 'already borrowed: BorrowMutError', src/main.rs:39:23
我认为&& 是一个短路运算符,这意味着两个表达式不会同时存在,所以两个可变引用不应该同时存在。
【问题讨论】:
-
通过推断丢失的部分,我得到了this code,它实际上可以编译。该问题无法重现。您是否使用旧版本的编译器?
-
@E_net4ishere 我每晚使用 1.49.0。顺便说一句,我已经更新了我的问题,你可以在 Rust Playground 上试试。
-
感谢您修复示例!我猜想 rust 编译器在为可变句柄执行析构函数时会立即考虑整个表达式。您可以通过将
&&的左侧拉到先前的声明中来解决此问题并仍然保持短路。