Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Gaukler
Oct 9, 2012


piratepilates posted:

I'm trying to learn some Rust since it seems like a pretty rad idea, so far I've been trying to do some simple data structures to figure it all out.

Here's what I have for a binary search tree, it compiles and runs but the insertion doesn't fully work -- it seems to remove all the past changes each time you insert a new node:

http://is.gd/qhiZkq
code:
fn main() {
    let mut butt = BSTNode::new(5);
    println!("{:?}", butt);
    butt.insert(7);
    println!("{:?}", butt);
    butt.insert(2);
    println!("{:?}", butt);
    butt.insert(1);
    butt.insert(3);
    butt.insert(4);
    butt.insert(6);
    butt.insert(8);
    println!("{:?}", butt);

}

#[derive(Debug)]
struct BSTNode {
    value: i32,
    left: Option<Box<BSTNode>>,
    right: Option<Box<BSTNode>>
}

impl BSTNode {
    fn new(value: i32) -> BSTNode {
        BSTNode {
            value: value,
            left: None,
            right: None
        }
    }
    
    fn insert(&mut self, value: i32) {
        match (self.value > value, self.left.take(), self.right.take()) {
            (true, None, _) => self.left = Some(Box::new(BSTNode::new(value))),
            (true, Some(ref mut left), _) => left.insert(value),
            (false, _,  None) => self.right = Some(Box::new(BSTNode::new(value))),
            (false, _, Some(ref mut right)) => right.insert(value),
        }
    }
}
Which prints:

code:
BSTNode { value: 5, left: None, right: None }
BSTNode { value: 5, left: None, right: Some(BSTNode { value: 7, left: None, right: None }) }
BSTNode { value: 5, left: Some(BSTNode { value: 2, left: None, right: None }), right: None }
BSTNode { value: 5, left: None, right: None }
Anyone know how I screwed up?

Also how far off base is everything I did idiomatically-wise?

Also what exactly is 'self.left.take()' doing? It fails compiling without it with the message 'cannot move out of borrowed content' and I somehow googled my way in to using it.

edit: alright well scratch why it doesn't work, take() just replaces the content with a None, which is why my children are disappearing. How do I borrow the self.left and self.right in the match otherwise?

I'm quite new to Rust myself so I spent some time wrestling the borrow checker, but the following works: (http://is.gd/nVAEU0)

code:
fn main() {
    let mut butt = BSTNode::new(5);
    println!("{:?}", butt);
    butt.insert(7);
    println!("{:?}", butt);
    butt.insert(2);
    println!("{:?}", butt);
    butt.insert(1);
    butt.insert(3);
    butt.insert(4);
    butt.insert(6);
    butt.insert(8);
    println!("{:?}", butt);

}

#[derive(Debug)]
struct BSTNode {
    value: i32,
    left: Option<Box<BSTNode>>,
    right: Option<Box<BSTNode>>
}

impl BSTNode {
    fn new(value: i32) -> BSTNode {
        BSTNode {
            value: value,
            left: None,
            right: None
        }
    }
    
    fn insert(&mut self, value: i32) {
    
        if self.value > value {
            match self.left {
                Some(ref mut left) => left.insert(value),
                None => self.left = Some(Box::new(BSTNode::new(value))),
            }
        } else {
            match self.right {
                Some(ref mut right) => right.insert(value),
                None => self.right = Some(Box::new(BSTNode::new(value))),
            }
        }
    }
}
Prints:
code:
BSTNode { value: 5, left: None, right: None }
BSTNode { value: 5, left: None, right: Some(BSTNode { value: 7, left: None, right: None }) }
BSTNode { value: 5, left: Some(BSTNode { value: 2, left: None, right: None }), right: Some(BSTNode { value: 7, left: None, right: None }) }
BSTNode { value: 5, left: Some(BSTNode { value: 2, left: Some(BSTNode { value: 1, left: None, right: None }), right: Some(BSTNode { value: 3, left: None, right: Some(BSTNode { value: 4, left: None, right: None }) }) }), right: Some(BSTNode { value: 7, left: Some(BSTNode { value: 6, left: None, right: None }), right: Some(BSTNode { value: 8, left: None, right: None }) }) }
Which looks right by my checking. I THINK the problem was when you do (self.value > value, self.left, self.right), you implicitly create a new Tuple which borrows self.left and self.right, so you can't use them in your match arms.

Adbot
ADBOT LOVES YOU

Gaukler
Oct 9, 2012


gonadic io posted:

It's a common tale. People, myself included, often feel like they're "doing it wrong" but as you say, it's rarely actually needed.

Having said that, god I love nom's zero copy stuff. Turning a flat file into a complex AST, all the strings only references into the original one. Luckily my files are small enough I can just read them into memory and don't have to figure out the streaming api.

nom is real good. I’m converting a thing from using hand-rolled parsers (because “I’m only going to need to parse a couple things!”)

I’m trying to not use the macros though, have you found good resources on that? Function calls seem to be the preferred new way, but the documentation still mixes the two and most tutorials are for the macro style.

Gaukler
Oct 9, 2012


You could model the state transition with two different types so you don’t have to litter Option checks everywhere. A DisconnectedNetworkManager that holds connection options and can connect() to return a ConnectedNetworkManager that has a Peer (not Option<Peer>) field and can send().

This way, your ConnectedNetworkManager lifetime will also line up with your Peer lifetime as well.

This might not make sense if you were expecting it to do a bunch of state transitions and you really do need to keep checking that you’re connected, though.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply