How to move an owned pointer - rust

For reference, I'm using Rust 0.7.
I'm trying to create a stack implementation using an owned linked list and I'm running into trouble.
trait Stack<T> {
fn push(&mut self, item : T);
fn pop(&mut self) -> Option<T>;
}
enum Chain<T> {
Link(T, ~Chain<T>),
Break
}
impl<T> Stack<T> for ~Chain<T> {
fn push(&mut self, item : T) {
*self = ~Link(item, *self);
}
fn pop(&mut self) -> Option<T> {
None
}
}
When I try to rustc stack.rs I get the following error:
stack.rs:13:28: 13:34 error: cannot move out of dereference of & pointer
stack.rs:13 *self = ~Link(item, *self);
^~~~~~
I don't know how I could overcome this or what I could do differently to allow this. It seems like I should be able to create this data structure without using managed pointers, but I haven't seen a lot of documentation on this sort of thing.

Either assignment from self (which I think includes constructing a new thing out of it, as in the case of Link(item, *self) implies a move. This means that in the process of constructing the new Link that self becomes unusable, because:
"After a value has been moved, it can no longer be used from the source location and will not be destroyed there."
The Right Way™ is probably best documented by what's done in this example in the stdlib. It's a doubly linked list, and it is managed, but it's mutable, and I hope copy free. There's also list of useful container types, too.
I did manage to get this immutable version of your datastructure working, however.
trait Stack<T> {
fn push(self, item : T) -> Self;
fn pop(self) -> Option<(T, Self)>;
fn new() -> Self;
}
#[deriving(Eq, ToStr)]
enum Chain<T> {
Link(T, ~Chain<T>),
Break
}
impl<T> Stack<T> for Chain<T> {
fn push(self, item : T) -> Chain<T> {
Link(item, ~self)
}
fn pop(self) -> Option<(T, Chain<T>)> {
match self {
Link(item, ~new_self) => Some((item, new_self)),
Break => None
}
}
fn new() -> Chain<T> {
Break
}
}
fn main() {
let b : ~Chain<int> = ~Stack::new();
println(b.push(1).push(2).push(3).to_str());
}

Related

Implementing a dynamic-typed LinkedList in Rust

This is a follow-up on the question asked here: Possible to implement dynamically-typed linked list in safe Rust?
I successfully implemented a dynamic type LinkedList using the std::any::Any trait.
However, I want to challenge myself by trying to implement it in another way, e.g. using generic type - Node where T can be any type, u32, u64, String, ...
Example
Node<String> -> Node<u32> -> Node<u64> -> Node<String> -> ...
My approach is to use a trait called Next to give Node<T> the ability to "go next".
Node<T> looks like this.
struct Node<T> {
data: T,
next: Option<Rc<RefCell<dyn Next>>>,
}
The trait Next looks like this.
pub trait Next {
fn borrow_next(&self) -> Option<Ref<dyn Next>>;
fn set_next(&mut self, next: Rc<RefCell<dyn Next>>);
}
These are the implementation of Next for any Node.
impl<T> Next for Node<T> {
fn set_next(&mut self, next: Rc<RefCell<dyn Next>>) {
self.next = Some(next);
}
fn borrow_next(&self) -> Option<Ref<dyn Next>> {
match &self.next {
None => None,
Some(stmt) => Some(stmt.borrow()),
}
}
}
Here are the implementations for the actual struct Node<T>.
impl<T> Node<T> {
pub fn new<P>(data: P) -> Node<P> {
Node::<P> { data, next: None }
}
pub fn new_wrapped<P>(data: P) -> Rc<RefCell<Node<P>>> {
Rc::new(RefCell::new(Node::<P>::new(data)))
}
pub fn into_wrapped(self) -> Rc<RefCell<Self>> {
Rc::new(RefCell::new(self))
}
pub fn borrow_data(&self) -> &T {
&self.data
}
pub fn set_data(&mut self, data: T) {
self.data = data;
}
}
Lastly, the declaration and its implementations of methods of struct DynLinkedList, holding two fields, head and tail, look like this.
struct DynLinkedList {
head: Option<Rc<RefCell<dyn Next>>>,
tail: Option<Rc<RefCell<dyn Next>>>,
}
impl DynLinkedList {
pub fn new_empty() -> Self {
Self {
head: None,
tail: None,
}
}
pub fn new_with_node(node: Rc<RefCell<dyn Next>>) -> Self {
Self {
head: Some(node.clone()),
tail: Some(node),
}
}
pub fn append(&mut self, node: Rc<RefCell<dyn Next>>) {
self.tail.take().map_or_else(
|| self.head = Some(node.clone()),
|old_tail| old_tail.borrow_mut().set_next(node.clone()),
);
self.tail = Some(node);
}
}
Here comes the problem:
I am unable to access the data field of Node<T> as it is being treated as a trait object dyn Next by the compiler.
For example, this test would not work:
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dynll_new_with_node() {
let node = Node::<u32>::new(77_u32);
let dynll = DynLinkedList::new_with_node(node.into_wrapped());
assert_eq!(&dynll.head.unwrap().borrow().borrow_data(), &77);
assert_eq!(&dynll.tail.unwrap().borrow().borrow_data(), &77)
}
}
The compiler error is:
error[E0599]: no method named `borrow_data` found for struct `Ref<'_, (dyn Next + 'static)>` in the current scope
--> src/dyn_ll_idea_five.rs:125:47
|
125 | assert_eq!(&*dynll.head.unwrap().borrow().borrow_data(), &77);
| ^^^^^^^^^^^ method not found in `Ref<'_, (dyn Next + 'static)>`
But, when the .borrow() after .unwrap() returns, it should return an object of type Node which would have the method .borrow_data(), how can I let Rust know that this is the case? Thank you.
I would effectively want to be able to do this:
let mut list = DynLinkedList::new();
list.push_front("hello".to_string());
list.push_back("world".to_string());
list.push_front(123);
list.push_back(456);
assert_eq!(list.pop_front(), Some("hello".to_string()));
assert_eq!(list.pop_back(), Some("world".to_string()));
assert_eq!(list.pop_front(), Some(123));
assert_eq!(list.pop_back(), Some(456));
Well, nowhere in the definition of trait Next does it talk about objects of type Node. Thus, how would the compiler ever know that you can call borrow_data on it? That's where you'd do the downcast via the Any trait.
What's more, the compiler would also want to know which sort of Node we're talking about. Node<i32> or Node<String> or what? And that's downright impossible because your list is dynamic and hence whatever type is contained within a node is also dynamic.
Let's take your example:
Node<String> -> Node<u32> -> Node<u64> -> Node<String> -> ...
So if that's your list, then, using very rough ugly pseudocode, what about this:
let x: String = my_list.head.borrow_data();
let y: u32 = my_list.head.next.borrow_data();
let z: u64 = my_list.head.next.next.borrow_data();
You see the problem here? How is the compiler to know, at compile time, that the third item in the list has type u64? This just isn't a case where generics work in the way you want it.

Make Box<Self> function parameter mutable

I've got this code snippet (playground link) where I'm basically trying to change a trait implementation to allow a state change for the struct it's applied to.
The current method signature is:
fn approve(self: Box<Self>) -> Box<dyn State>
, but I need to make it into something like
fn approve(&mut self: Box<Self>) -> Box<dyn State>
This doesn't compile. I've yet to see a Rust &mut self parameter definition along with a type, though I'm not sure why that would be an issue.
If I try:
fn approve(&mut self) -> Box<dyn State>
I get other compile-time errors when I try to return an unmodified self from the method.
For a little bit more context (before checking the playground), here are some relevant code bits:
trait State {
fn approve(self: Box<Self>) -> Box<dyn State>;
}
struct Draft {
approve_count: u8,
}
impl State for Draft {
fn approve(self: Box<Self>) -> Box<dyn State> {
// self.approve_count += 1;
if self.approve_count == 2 {
Box::new(Approved {})
} else {
self
}
}
}
struct Approved {}
impl State for Approved { ... }
What I would like to do is be able to uncomment the self.approve_count += 1; line and have it work.
The correct syntax for a mutable reference is:
fn approve(self: &mut Box<Self>)
...but then you won't be able to return self as Box<dyn State> because you're only holding a reference to self.
If all you need is for self.approve_count += 1 to work, you don't need to switch to &mut self, you can simply declare mut self: Box<Self>:
impl State for Draft {
fn approve(mut self: Box<Self>) -> Box<dyn State> {
self.approve_count += 1;
if self.approve_count == 2 {
Box::new(Approved {})
} else {
self
}
}
...
}
Playground
That code is a bit suspect in that it modifies self.approved_count even in the case where the function returns a completely new Approved instance (and discards the just incremented value), but that may be fixed by moving the increment into the else clause and adjusting the test as appropriate.

How do I get automagic convertions from Rust Into trait?

I have a struct Object for which I have many implementations of From (including isize and &str). I got the sense from this article where Into is described as 'genius' that things could get automatically converted for me. I've incorporated the suggestions that people have made, and made something that is standalone in the playground but it still gets a couple of errors.
#[derive(Copy,Clone)]
pub union Object {
d:f64,
i:isize,
}
impl From<isize> for Object {
fn from(i:isize) -> Self {
Object{i}
}
}
impl From<f64> for Object {
fn from(d:f64) -> Self {
Object{d}
}
}
pub fn old_convert(foo: Object, _elements: &[Object]) -> Object {
foo
}
pub fn new_convert<'a,T>(foo: impl Into<Object>, elements: &'a [T]) -> Object
where
&'a T: Into<Object>,
Object: From<T>,
{
let mut el = Vec::new();
for o in elements.iter() {
el.push(o.into())
}
old_convert(foo.into(),&el)
}
#[test]
fn testOldConvert() {
old_convert(Object::from(42), &[Object::from(3.1415)]);
}
#[test]
fn testNewConvert() {
new_convert(42, &[3.1415]);
}
So you can see what I currently do. I'd like to not have to include all the Object::from(...) when I use my function.
There is 1 error, and 1 problem:
I don't know how to implement the From it's asking for
I don't want to create the temporary vector... surely there's some zero-cost abstraction that allows me to pass the converted array along

Rust Implement Iterator

So I am currently learning Rust and have a question on how to implement a non-consuming Iterator.
I programmed a Stack:
struct Node<T>{
data:T,
next:Option<Box<Node<T>>>
}
pub struct Stack<T>{
first:Option<Box<Node<T>>>
}
impl<T> Stack<T>{
pub fn new() -> Self{
Self{first:None}
}
pub fn push(&mut self, element:T){
let old = self.first.take();
self.first = Some(Box::new(Node{data:element, next:old}));
}
pub fn pop(&mut self) -> Option<T>{
match self.first.take(){
None => None,
Some(node) =>{
self.first = node.next;
Some(node.data)
}
}
}
pub fn iter(self) -> StackIterator<T>{
StackIterator{
curr : self.first
}
}
}
pub struct StackIterator<T>{
curr : Option<Box<Node<T>>>
}
impl<T> Iterator for StackIterator<T>{
type Item = T;
fn next (&mut self) -> Option<T>{
match self.curr.take(){
None => None,
Some(node) => {
self.curr = node.next;
Some(node.data)
}
}
}
}
With a Stack Iterator, which is created calling the iter() Method on a Stack. The Problem: I had to make this iter() method consuming its Stack, therefore a stack is only iteratable once. How can I implement this method without consuming the Stack and without implementing the copy or clone trait?
How can I implement this method without consuming the Stack and without implementing the copy or clone trait?
Have StackIterator borrow the stack instead, and the iterator return references to the items. Something along the lines of
impl<T> Stack<T>{
pub fn iter(&self) -> StackIterator<T>{
StackIterator{
curr : &self.first
}
}
}
pub struct StackIterator<'stack, T: 'stack>{
curr : &'stack Option<Box<Node<T>>>
}
impl<'s, T: 's> Iterator for StackIterator<'s, T>{
type Item = &'s T;
fn next (&mut self) -> Option<&'s T>{
match self.curr.as_ref().take() {
None => None,
Some(node) => {
self.curr = &node.next;
Some(&node.data)
}
}
}
}
(I didn't actually test this code so it's possible it doesn't work)
That's essentially what std::iter::Iter does (though it's implemented as a way lower level).
That said learning Rust by implementing linked lists probably isn't the best idea in the world, linked lists are degenerate graphs, and the borrow checker is not on very friendly terms with graphs.

Passing on lifetimes of underlying reference fields?

I'm trying to make two structs that operate on an underlying dataset; one providing immutable "read" operations, the other allowing modification. For this to work, I need to be able to use the read functions from within the modifying object - as such I create a temporary new read object within the modifier function with a view onto the underlying data.
Here's some code:
struct Read<'db> {
x: &'db i32
}
impl<'db> Read<'db> {
pub fn get(&'db self) -> &'db i32 { self.x }
}
struct Write<'db> {
x: &'db mut i32
}
impl<'db> Write<'db> {
fn new(x: &mut i32) -> Write { Write{x: x} }
fn as_read(&'db self) -> Read<'db> {
Read{x: self.x}
}
pub fn get(&'db self) -> &'db i32 { self.as_read().get() }
}
fn main() {
let mut x = 69i32;
let y = Write::new(&mut x);
println!("{}", y.get());
}
It doesn't compile - it seems that despite my best efforts, the lifetime of the reference returned from Read::get is bound to the Write::get's scope, rather than the Write's 'db lifetime. How can I make it compile? (And, is what I want to do possible? Is it the simplest/most concise way of doing it?)
The point the compiler is trying to get across is that &'db self actually means self: &'db Write<'db>. This means that you tie the reference AND the type to the same lifetime. What you actually want in your case is self: &'a Write<'db> where 'a lives just for the as_read function. To be able to return a 'db reference from a 'a reference, you need to specify that 'a lives at least as long as 'db by constraining 'a: 'db.
fn as_read<'a: 'db>(self: &'a Write<'db>) -> Read<'db> {
Read{x: self.x}
}
pub fn get<'a: 'db>(self: &'a Write<'db>) -> &'db i32 { self.as_read().get() }
or more concisely
fn as_read<'a: 'db>(&'a self) -> Read<'db> {
Read{x: self.x}
}
pub fn get<'a: 'db>(&'a self) -> &'db i32 { self.as_read().get() }
Try it out in the Playground

Resources