Rc::into_inner return None , But i actuall had it

:slight_smile:
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 :kissing_smiling_eyes:

my code is below :kissing_smiling_eyes:

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 the Rc 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 Nodes 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 Rcs 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

2 Likes

Thanks a lot!!,
it seems i l missing something about Rc , i will read it again :kissing_smiling_eyes:

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.