Created
January 5, 2017 20:46
-
-
Save rezich/27595fd405c62a88348a60790b6b1b33 to your computer and use it in GitHub Desktop.
learning Rust by making a game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
I'm learning Rust by making a game. | |
This game would be very simple to make, unsafely, in C/C++, | |
and I'm hoping that by making it in Rust, I'll learn the core concepts | |
of ownership and such. | |
But right now, I'm stuck. | |
Here's what I'm *trying* to do, in C++: | |
struct Bar { | |
std::string title; | |
std::vector<Bar> bars; | |
Bar *parent; | |
Bar *add_bar(); | |
} | |
struct Foo { | |
Bar root_bar; | |
Bar *current_bar; | |
void set_current_bar(Bar *bar); | |
void add_bar(); | |
void process(); | |
} | |
And here's what I have so far in Rust: | |
*/ | |
// container object for the entire game | |
struct Foo { | |
root_bar: Bar, | |
current_bar: Option<&Bar> | |
} | |
impl Foo { | |
fn new() -> Self { | |
Foo { | |
root_bar: Bar { | |
title: "root".to_string(), | |
bars: Vec::new(), | |
parent: None | |
} | |
} | |
} | |
fn set_current_bar(&self, bar: &Bar) { | |
// change which Bar `current_bar` "points" at | |
// (it will be used internally in this Foo) | |
} | |
fn add_bar(&self) { | |
// add a Bar to `current_bar`'s `bars`, | |
// then call set_current_bar() w/ the new Bar | |
} | |
fn process(&self) { | |
// "game loop" goes in here | |
} | |
} | |
// thing inside game, only exists within the confines of a Foo | |
struct Bar { | |
title: String, | |
bars: Vec<Bar>, | |
parent: Option<&Bar> | |
} | |
impl Bar { | |
fn add_bar(&self) -> &Bar { | |
// create a new Bar | |
// set new Bar's `parent` to this, | |
// push new Bar to this Bar's `bars` | |
// return reference to the new Bar, in `bars` | |
} | |
} | |
fn main() { | |
// create the Foo container and run the game | |
Foo::new().process(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Try this on for size.
What I did:
struct Bar
up underFoo
. This isn't required by any means, I just like to keep my data structures together.Foo
was missing a lifetime specifier, why? Because there was no guarantee that the reference toBar
would live for as long asFoo
itself. What if the reference got deallocated beforeFoo
did? Then you'd have a dangling pointer, no bueno.parent: Option<&Bar>
toparent: Option<Box<Bar>>
, a Box is a variable on the heap, which is required if you need nested data structures.current_bar: None
toFoo::new()
, because Rust won't let you initialise structs without filling in all the fields.unimplemented!()
toBar.add_bar()
to keep the compiler from whining about the missing return value.