【发布时间】:2019-06-11 18:03:39
【问题描述】:
我想用 Rust (Remove Nth Node From End of List) 解决一个 leetcode 问题。我的解决方案使用两个指针来查找要删除的Node:
#[derive(PartialEq, Eq, Debug)]
pub struct ListNode {
pub val: i32,
pub next: Option<Box<ListNode>>,
}
impl ListNode {
#[inline]
fn new(val: i32) -> Self {
ListNode { next: None, val }
}
}
// two-pointer sliding window
impl Solution {
pub fn remove_nth_from_end(head: Option<Box<ListNode>>, n: i32) -> Option<Box<ListNode>> {
let mut dummy_head = Some(Box::new(ListNode { val: 0, next: head }));
let mut start = dummy_head.as_ref();
let mut end = dummy_head.as_ref();
for _ in 0..n {
end = end.unwrap().next.as_ref();
}
while end.as_ref().unwrap().next.is_some() {
end = end.unwrap().next.as_ref();
start = start.unwrap().next.as_ref();
}
// TODO: fix the borrow problem
// ERROR!
// start.unwrap().next = start.unwrap().next.unwrap().next.take();
dummy_head.unwrap().next
}
}
我借用了链表的两个不可变引用。在找到要删除的目标节点后,我想删除一个并使另一个可变。以下每个代码示例都会导致编译器错误:
// ERROR
drop(end);
let next = start.as_mut().unwrap.next.take();
// ERROR
let mut node = *start.unwrap()
我不知道这个解决方案是否可以用 Rust 编写。如果我可以使不可变引用可变,我该怎么做?如果没有,是否有在使借用检查器满意的同时实现相同的逻辑?
【问题讨论】:
-
将不可变引用转换为可变引用几乎不是一个好主意。你应该首先借用可变的。
-
或者在你的数据结构中使用内部可变性,比如
RefCell。 -
我认为没有必要投反对票。不,如果没有 UB,你不能这样做,但这不是一个不合理的问题——尤其是对于来自像 C++ 这样的语言的用户来说,
constness 实际上更像是一个 suggestion 而不是 规则. -
翻译:“有可能朝自己的头部开枪吗?”
标签: data-structures rust mutability interior-mutability