Нестабильный заем в Русте - PullRequest
0 голосов
/ 12 октября 2019

Я новичок в Rust, я просто делаю упражнения. Есть связанный список. Например, 0-> 1-> 2-> 3-> 4 , обрежьте его по индексу 2, затем поменяйте местами оба, а затем составьте их. => 0 <-1 <-2 </strong> 3 <-4 </strong> => 2-> 1-> 0-> 4-> 3

#[derive(debug)]
struct Node{
    val: usize,
    next: Option<Box<Node>>,
}

impl Node {
    fn new(i: usize) -> Node {
    ...
    }

    fn reverse_at(self, k: usize) -> Box<Node> {
        let mut prev = None;
        let mut curr = Box::new(self);

        let first_part_tail = &mut curr;

        let mut i: usize = 0;
        while i <= k {
            let next = curr.next.take();
            curr.next = prev;
            match next {
                Some(next_node) => {
                    prev = Some(curr);
                    curr = next_node;
                }
                None => return curr,
            }
            i += 1;
        }

        let head = prev.unwrap();
        prev = None;
        loop {
            let next = curr.next.take();
            curr.next = prev;
            match next {
                Some(next_node) => {
                    prev = Some(curr);
                    curr = next_node;
                }
                None => {
                    first_part_tail.next = Some(curr);
                    return head;
                }
            }
        }
    }
}

Мне нужно получить изменяемый заем первого узла 0 и установить 0 .next = 4 после получения последнего узла 4 в конце функции. Но владелец узла 0 уже передан узлу 1 . Очевидно, что error[E0499]: cannot borrow `curr.next` as mutable more than once at a time происходит, я не знаю, что делать. Это застряло у меня надолго. Любая помощь, пожалуйста.

play.rust-lang.org /...

&, я полагаю, что эта функция изменит сам узел. И я не знаю, как изменить собственную ссылку на новый узел, поэтому я использовал self. Если кто-то может изменить это, это тоже помогает. Возможно, измените эту функцию на

fn reverse_at(&mut self, k:usize){
    ...
}

1 Ответ

0 голосов
/ 06 ноября 2019

@ Ultrasaurus спасибо за учебный ресурс https://rust -unofficial.github.io / too-many-lists / . Теперь я решаю проблему, хотя это занимает несколько раз.

Окончательный код здесь детская площадка

Немного странно, что мой LinkedNumber.head равен Node, потому что у LinkedNumber всегда есть голова, может быть ноль, но не ноль. Возможно, это должно быть Box<Node>.

В строке 71 я использую ptr::read, оно будет

Считывает значение из src, не перемещая его.

mem::take тоже нормально. Но для этого нужно указать Node со значением по умолчанию trait Default.

Чем я использую Box::new для перемещения узла из стека в кучу. (Нет необходимости делать это, если LinkedNumber.head равно Box<Node>)

В строке 73 отметьте raw_pointer *const Node заголовка.

В строке 94, если ссылкабыла разбита на две части, приведена *const Node к *mut Node, разыменована, установлена ​​(*ptr).next с последним узлом исходной ссылки.

Как проверить: изменить число в num.reverse_at(3) в строке 171, работает нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...