- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
>, left: Opti-6ren">
我正在尝试用 Rust 实现 BST。我的结构看起来像这样:
pub struct Node<T> {
key: T,
parent: Option<Box<Node<T>>>,
left: Option<Box<Node<T>>>,
right: Option<Box<Node<T>>>,
}
我正在研究一种寻找当前节点后继者的方法。在与借用检查器进行了长时间的斗争之后,我成功了,但现在看起来像这样:
//If right node exists - successor is a min node in it.
//Else - go up a parent node. If parent is None, no successor.
//If origin was parent's left node - parent is a successor.
//Else - go up another level.
pub fn succ(&self) -> Option<Box<Node<T>>> {
match self.right {
Some(ref node) => Some(node.min()),
None => {
let mut origin = Box::new(self.clone()); //To match types
let mut parent = origin.parent.clone(); //`Node<T>` not a copy type
loop {
let parent_node = match parent.clone() {
Some(node) => node,
None => break,
};
let right_of_parent = match parent_node.clone().right {
Some(node) => node,
None => break,
};
if *origin != *right_of_parent {
break;
}
origin = parent_node;
parent = origin.parent.clone();
}
parent
}
}
}
如果我删除所有 .clone()
,编译器将开始报错“部分移动值”和“无法分配因为借用”错误。有没有办法让这段代码更加地道,而不是克隆 hell ?
更新:
想发布我最终得到的解决方案。
首先,上面的代码不起作用,因为父字段包含的不是引用,而是父节点的副本。所以最后问题变成了“如何实现对父节点的引用”。
我考虑了下面的答案,一些books和 relevant answers最后我得出结论,对于一个我什至不打算在线发布的玩具项目来说,它不值得。我发现不是最有效但绝对更简单的解决方案 - 根本不使用父引用。
我从上面的结构中删除了父字段并创建了另一个结构:
pub struct Tree<T> {
root: Option<Box<Node<T>>>,
}
现在我从树的根部搜索父节点。我的 succ
函数现在看起来像这样:
fn succ<'a>(&'a self, node: &'a Node<T>) -> Option<&Node<T>> {
match node.right {
Some(ref rnode) => rnode.min(),
None => {
let mut succ = None;
let mut root = self.root.as_ref();
loop {
root = match root {
Some(ref rootnode) => {
match node.key.cmp(&rootnode.key) {
Ordering::Less => {
succ = Some(&***rootnode);
rootnode.left.as_ref()
}
Ordering::Greater => rootnode.right.as_ref(),
Ordering::Equal => break,
}
}
None => break,
}
}
succ
}
}
}
最佳答案
欢迎使用 Rust 和 Stack Overflow!
这里的主要问题是 Node
定义:
pub struct Node<T> {
key: T,
parent: Option<Box<Node<T>>>,
left: Option<Box<Node<T>>>,
right: Option<Box<Node<T>>>,
}
在 Rust 中,Box<T>
拥有 值而不是可以别名的指针。您将无法创建任何非平凡的树。
而不是 Box
,你可以试试引用计数 Rc<T>
.您可以使用 Weak
父链接的指针,以避免让它们保持事件状态:
use std::rc::{Rc,Weak};
pub struct Node<T> {
key: T,
parent: Option<Weak<Node<T>>>,
left: Option<Rc<Node<T>>>,
right: Option<Rc<Node<T>>>,
}
排序后,您就不会使用引用。每次你做这样的事情:
let mut parent = origin.parent; //.clone();
在你的版本中 origin.parent
类型为 Option<Box<Node<T>>>
,您正在尝试移动 Option
场外origin
- 因此你必须添加 clone()
(它克隆了 Box
中的节点,而不仅仅是指针!)。但是,您并不是真的想搬出去;您只需要对它的引用,例如:
let parent = &origin.parent;
或者执行 None
同时检查:
match origin.parent {
Some(ref parent_ptr) => { ... },
None => { ... }
}
希望对您有所帮助!
关于rust - 搜索BST节点的Successor, "clone to satisfy borrow checker"灾难,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39072257/
我写了一个我认为是 quite interesting question 的答案,但不幸的是,在我发布之前,该问题已被作者删除。我在这里重新发布问题的摘要和我的答案,以防其他人有用。 假设我有一个 S
有没有办法写约束: C t1 t2 :: Constraint 如果 t2 与 t1 匹配,它“满足”(这是正确的词)。 例如: C (forall a. Num a => a -> a -> a)
我正在尝试用这段代码求解方程: a = [-0.0008333 -0.025 -0.6667 -20]; length_OnePart = 7.3248; xi = -6.4446; yi = -16
我知道我可以关闭 MySQL 中的安全模式,所以我不会尝试解决这个问题。 我有一个简单的表格: create table rubbish( id int auto_increment prim
尝试刷新我的 sencha extjs 应用程序并总是收到此错误: 命令: sencha 应用程序刷新 sencha 应用升级 总是同样的错误: [ERR] Cannot satisfy requir
我正在尝试为我的项目创建一个测试套件,HaskSplit在我的 .cabal 配置中: -- Initial HaskSplit.cabal generated by cabal init. For
我有 pc/sc 读卡器和非接触式卡(mifare 卡),我可以连接到该卡,并且我也成功执行 getdate 命令,但是当我想进行身份验证时,我看到此错误“6982:安全状态不满足”我已经尝试了这 3
简而言之,流程如下: inputChannel->transformer->firstOutboundAdapter->pollingOutboundAdapter 概要:inputChannel 接
这个问题在这里已经有了答案: Why do try!() and ? not compile when used in a function that doesn't return Option o
我正在尝试切片矢量并在 Rust 中同时打印它。这是我的代码: fn main() { let a = vec![1, 2, 3, 4]; println!("{:?}", a[1..
我正在尝试自定义约束 菜单栏类: import UIKit class ManuBar: UIView { override init(frame: CGRect) { sup
我遇到了这个问题,我有一个聊天服务器需要与托管在 aws 中的 lambda 服务进行通信,但云前端会引发以下错误。 BODY: ERROR: The request could not be s
我有一个包含Arc>的结构,我试图添加一个获取self所有权的方法,并将所有权移到新线程中并启动它。但是,我得到了错误 error[E0277]: the trait bound `std::sync
我遇到了一个编译错误,似乎突出显示了我对类型系统不了解的内容。 我想将字符串转换为整数,如果字符串不是有效整数,则带有自定义 panic 消息。我做一个match在 Result由 parse() 返
这是应用过滤器后复制数据的代码。 Sub read_excel_file(path_to_current_work_book As String, path_to_destination_work
我们有一个 shell 脚本,可以自动准备虚拟环境,然后在其中运行测试。部分脚本安装要求: pip install -r requirements.txt 当脚本多次运行时,它会针对每个要求打印一条警
总是遇到 FoodTracker 教程;遵循此步骤:“实现自定义控件” https://developer.apple.com/library/content/referencelibrary/Get
我收到此错误: Unable to simultaneously satisfy constraints. Probably at least one of the constraints in th
我有一个 UITableViewCell我正在创建,并且我正在使用带有完全在代码中构建的约束的自动布局。 虽然应用程序中的实际输出很好(即,它看起来就像我设计的那样),但我收到了著名的“无法同时满足约
这个问题在这里已经有了答案: Disable autolayout constraint error messages in debug console output in Xcode (5 个回答)
我是一名优秀的程序员,十分优秀!