i am learning for rust Link-List and i write a insert method , cause i want to have both head pointer and tail pointer , i use Rc smart pointer, and when i need to take element from Rc by using Rc::into_inner to get it , i got None, i am confuse about it , i search for bing and also ask Ai , but nothing works , thansk for your guys
my code is below
use std::rc::Rc;
#[allow(dead_code)]
fn main() {
let mut l = Link::new();
l.insert(12);
}
#[derive(Debug)]
struct Node{
v:i32,
next:Option<Box<Node>>,
}
#[derive(Debug)]
struct Link{
head : Option<Rc<Box<Node>>>,
tail : Option<Rc<Box<Node>>>,
}
impl Node{
fn new()->Box<Self>{
Box::new(Node{v:12,next:None,})
}
fn from(v:i32)->Box<Self>{
Box::new(Node{v,next:None})
}
}
impl Link{
fn new()->Self{
let new_node:Box<Node> = Node::new();
let head = Rc::new(new_node);
let tail = Rc::clone(&head);
Link{head:Some(head),tail:Some(tail)}
}
fn insert( self:&mut Self,v:i32)
{
let old :Rc<Box<Node>> = self.head.take().unwrap();
let old: Box<Node> = Rc::into_inner(old).unwrap();
let mut new:Rc<Box<Node>> = Rc::new(Node::from(v));
let new_mut:& mut Box<Node> = Rc::get_mut(&mut new).unwrap();
new_mut.next = Some(old);
self.head = Some(new);
()
}
fn walk(self:Self)
{
let head:Box<Node> = Rc::into_inner(self.head.unwrap()).unwrap();
let tail:Box<Node> = Rc::into_inner(self.tail.unwrap()).unwrap();
let mut p = head;
loop{
print!("{} ->",p.v);
p = p.next.unwrap();
if std::ptr::eq(&p,&tail)
{
break;
}
}
}
}
i run cargo check
and i run cargo run
From the documentation of Rc::into_inner
:
Returns the inner value, if the
Rc
has exactly one strong reference.Otherwise,
None
is returned and theRc
is dropped.
If it's returning None
then it means your Rc
has multiple strong references.
From a quick glance at your code it seems Link
is initialized with head = tail
, then in insert
you try to call Rc::into_inner
on head
, but it fails because there's a second strong reference in tail
.
A more fundamental issue seems to be that your Node
s exclusively own the "next" element, since they hold a Box
to that. But you also seem to want to hold a Rc
that owns the last element, and this is not possible. For a simple linked list I would suggest you to avoid holding access to the last element. If you really want to hold a Rc
to it then you'll have to use Rc
s everywhere, but that will complicate other parts of the code.
If you're a beginner I would advise against learning using data structures like linked lists, they don't really play well with the borrow checker and the ownership system. There's even an online book about this Introduction - Learning Rust With Entirely Too Many Linked Lists
Thanks a lot!!,
it seems i l missing something about Rc , i will read it again
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.