YLy*_*Lyu 12 smart-pointers dereference rust
我正在尝试用 Rust 解决一些 Leetcode 问题。然而,我在 LeetCode 的实现过程中遇到了一些困难TreeNode。
use std::cell::RefCell;
use std::rc::Rc;
// TreeNode data structure
#[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,
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果我想做一个中序遍历,如何解开 的TreeNode对象Option<Rc<RefCell<TreeNode>>>,访问它.val .left .right并将它们作为输入传递到递归函数中?
我努力了:
pub struct Solution;
impl Solution {
pub fn inorder_traversal(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
let mut ret: Vec<i32> = vec![];
match root {
Some(V) => Solution::helper(&Some(V), &mut ret),
None => (),
}
ret
}
fn helper(node: &Option<Rc<RefCell<TreeNode>>>, ret: &mut Vec<i32>) {
match node {
None => return,
Some(V) => {
// go to the left branch
Solution::helper(
(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
.into_inner()
.left,
ret,
);
// push root value on the vector
ret.push(Rc::try_unwrap(Rc::clone(V)).unwrap_err().into_inner().val);
// go right branch
Solution::helper(
(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
.into_inner()
.right,
ret,
);
}
}
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
(游乐场)
编译器抱怨:
use std::cell::RefCell;
use std::rc::Rc;
// TreeNode data structure
#[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,
}
}
}
Run Code Online (Sandbox Code Playgroud)
但如果我尝试这个建议,它也会抱怨:
pub struct Solution;
impl Solution {
pub fn inorder_traversal(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
let mut ret: Vec<i32> = vec![];
match root {
Some(V) => Solution::helper(&Some(V), &mut ret),
None => (),
}
ret
}
fn helper(node: &Option<Rc<RefCell<TreeNode>>>, ret: &mut Vec<i32>) {
match node {
None => return,
Some(V) => {
// go to the left branch
Solution::helper(
(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
.into_inner()
.left,
ret,
);
// push root value on the vector
ret.push(Rc::try_unwrap(Rc::clone(V)).unwrap_err().into_inner().val);
// go right branch
Solution::helper(
(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
.into_inner()
.right,
ret,
);
}
}
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
解开并
T从Option<Rc<RefCell<T>>>
您确实不想尝试通过//删除Option、 theRc或 the中的值。相反,对 进行模式匹配,然后调用来获取对 的引用。RefCellunwraptry_unwrapinto_innerOptionborrowRefCellT
此外:
if let而不是声明。matchsnake_case. V不是一个合适的名字。ret。pub fn inorder_traversal(root: Option<Rc<RefCell<TreeNode>>>) -> Vec<i32> {
fn helper(node: &Option<Rc<RefCell<TreeNode>>>, ret: &mut Vec<i32>) {
if let Some(v) = node {
let v = v.borrow();
helper(&v.left, ret);
ret.push(v.val);
helper(&v.right, ret);
}
}
let mut ret = vec![];
if let Some(v) = root {
helper(&Some(v), &mut ret);
}
ret
}
Run Code Online (Sandbox Code Playgroud)
就我个人而言,我不喜欢被迫构建Some,因此我可能会重新组织代码,这也允许我将其作为方法粘贴在TreeNode:
impl TreeNode {
pub fn inorder_traversal(&self) -> Vec<i32> {
fn helper(node: &TreeNode, ret: &mut Vec<i32>) {
if let Some(ref left) = node.left {
helper(&left.borrow(), ret);
}
ret.push(node.val);
if let Some(ref right) = node.right {
helper(&right.borrow(), ret);
}
}
let mut ret = vec![];
helper(self, &mut ret);
ret
}
}
Run Code Online (Sandbox Code Playgroud)
也可以看看:
| 归档时间: |
|
| 查看次数: |
7022 次 |
| 最近记录: |