Last active
November 25, 2015 02:30
-
-
Save bangedorrunt/a9927c63e5ca8f6e33e4 to your computer and use it in GitHub Desktop.
Rust tips
This file contains hidden or 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
| // Reference from: https://play.rust-lang.org/?gist=a571361967dc228330b3&version=stable | |
| trait Shape { | |
| fn draw(&self); | |
| } | |
| struct Square; | |
| impl Shape for Square { | |
| fn draw(&self) { println!("Square drawn."); } | |
| } | |
| struct Circle; | |
| impl Shape for Circle { | |
| fn draw(&self) { println!("Circle drawn."); } | |
| } | |
| struct Triangle; | |
| impl Shape for Triangle { | |
| fn draw(&self) { println!("Triangle drawn."); } | |
| } | |
| fn populate_shapes_by_ref<'a>() -> Vec<&'a Shape> { | |
| let s = Square; | |
| let c = Circle; | |
| let t = Triangle; | |
| let shapes: Vec<&Shape> = vec![ | |
| &s, &c, &t, | |
| ]; | |
| // Can't return shapes because s, c and t get deallocated | |
| // when the function returns, invalidating | |
| //return shapes; | |
| unimplemented!() | |
| } | |
| fn populate_shapes_by_box() -> Vec<Box<Shape>> { | |
| let shapes: Vec<Box<Shape>> = vec![ | |
| Box::new(Square), Box::new(Circle), Box::new(Triangle), | |
| ]; | |
| return shapes; | |
| } | |
| fn main() { | |
| for shape in populate_shapes_by_box() { | |
| shape.draw(); | |
| } | |
| } |
This file contains hidden or 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
| use List::*; | |
| enum List { | |
| // Explained from: http://andreiformiga.com/blog/?p=382 | |
| // If we try to declare the Cons case with `(u32, List)`, the compiler will say to us: | |
| // | |
| // error: illegal recursive enum type; wrap the inner value in a box to make it representable | |
| // | |
| // This means that `List` is trying to include a copy of itself inside it, and this can’t work | |
| // because the size of an `List` is not known in advance. A “naked” `List` in rust is a `value`, | |
| // not a reference. So to have a node in the list reference another, we have to make it a pointer. | |
| // The object referenced by a managed pointer will be boxed, and its lifetime will be managed | |
| // by the garbage collector. | |
| // | |
| // Cons: Tuple struct that wraps an element and a pointer to the next node | |
| Cons(u32, Box<List>), | |
| // Nil: A node that signifies the end of the linked list | |
| Nil, | |
| } | |
| // Methods can be attached to an enum | |
| impl List { | |
| // Create an empty list | |
| fn new() -> List { | |
| // `Nil` has type `List` | |
| Nil | |
| } | |
| // Consume a list, and return the same list with a new element at its front | |
| fn prepend(self, elem: u32) -> List { | |
| // `Cons` also has type List | |
| Cons(elem, Box::new(self)) | |
| } | |
| // Return the length of the list | |
| fn len(&self) -> u32 { | |
| // `self` has to be matched, because the behavior of this method | |
| // depends on the variant of `self` | |
| // `self` has type `&List`, and `*self` has type `List`, matching on a | |
| // concrete type `T` is preferred over a match on a reference `&T` | |
| match *self { | |
| // Can't take ownership of the tail, because `self` is borrowed; | |
| // instead take a reference to the tail | |
| Cons(_, ref tail) => 1 + tail.len(), | |
| // Base Case: An empty list has zero length | |
| Nil => 0 | |
| } | |
| } | |
| // Return representation of the list as a (heap allocated) string | |
| fn stringify(&self) -> String { | |
| match *self { | |
| Cons(head, ref tail) => { | |
| // `format!` is similar to `print!`, but returns a heap | |
| // allocated string instead of printing to the console | |
| format!("{}, {}", head, tail.stringify()) | |
| }, | |
| Nil => { | |
| format!("Nil") | |
| }, | |
| } | |
| } | |
| } | |
| fn main() { | |
| // Create an empty linked list | |
| let mut list = List::new(); | |
| // Append some elements | |
| list = list.prepend(1); | |
| list = list.prepend(2); | |
| list = list.prepend(3); | |
| // Show the final state of the list | |
| println!("linked list has length: {}", list.len()); | |
| println!("{}", list.stringify()); | |
| } |
This file contains hidden or 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
| // Reference from: https://play.rust-lang.org/?gist=3f13fa614a5f27a4d5e6&version=stable | |
| use List::*; | |
| enum List<'a> { | |
| // Explained from: http://andreiformiga.com/blog/?p=382 | |
| // If we try to declare the Cons case with `(u32, List)`, the compiler will say to us: | |
| // | |
| // error: illegal recursive enum type; wrap the inner value in a box to make it representable | |
| // | |
| // This means that `List` is trying to include a copy of itself inside it, and this can’t work | |
| // because the size of an `List` is not known in advance. A “naked” `List` in rust is a `value`, | |
| // not a reference. So to have a node in the list reference another, we have to make it a pointer. | |
| // The object referenced by a managed pointer will be boxed, and its lifetime will be managed | |
| // by the garbage collector. | |
| // | |
| // Cons: Tuple struct that wraps an element and a pointer to the next node | |
| Cons(u32, &'a List<'a>), | |
| // Nil: A node that signifies the end of the linked list | |
| Nil, | |
| } | |
| // Methods can be attached to an enum | |
| impl<'a> List<'a> { | |
| // Create an empty list | |
| fn new() -> List<'a> { | |
| // `Nil` has type `List` | |
| Nil | |
| } | |
| // Consume a list, and return the same list with a new element at its front | |
| fn prepend(&'a self, elem: u32) -> List<'a> { | |
| // `Cons` also has type List | |
| Cons(elem, &self) | |
| } | |
| // Return the length of the list | |
| fn len(&self) -> u32 { | |
| // `self` has to be matched, because the behavior of this method | |
| // depends on the variant of `self` | |
| // `self` has type `&List`, and `*self` has type `List`, matching on a | |
| // concrete type `T` is preferred over a match on a reference `&T` | |
| match *self { | |
| // Can't take ownership of the tail, because `self` is borrowed; | |
| // instead take a reference to the tail | |
| Cons(_, ref tail) => 1 + tail.len(), | |
| // Base Case: An empty list has zero length | |
| Nil => 0 | |
| } | |
| } | |
| // Return representation of the list as a (heap allocated) string | |
| fn stringify(&self) -> String { | |
| match *self { | |
| Cons(head, ref tail) => { | |
| // `format!` is similar to `print!`, but returns a heap | |
| // allocated string instead of printing to the console | |
| format!("{}, {}", head, tail.stringify()) | |
| }, | |
| Nil => { | |
| format!("Nil") | |
| }, | |
| } | |
| } | |
| } | |
| fn main() { | |
| // Create an empty linked list | |
| let list = List::new(); | |
| // Append some elements | |
| let list2 = list.prepend(1); | |
| let list3 = list2.prepend(2); | |
| let list4 = list3.prepend(3); | |
| // Show the final state of the list | |
| println!("linked list has length: {}", list4.len()); | |
| println!("{}", list4.stringify()); | |
| } |
This file contains hidden or 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
| // References from: https://play.rust-lang.org/?gist=98d98ed31a97bf765219&version=stable | |
| // A list of references pretty much forces you to to give each node its own local variable, | |
| // and you can't have arbitrarily many local variables in a function | |
| use List::*; | |
| enum List<'a> { | |
| // Explained from: http://andreiformiga.com/blog/?p=382 | |
| // If we try to declare the Cons case with `(u32, List)`, the compiler will say to us: | |
| // | |
| // error: illegal recursive enum type; wrap the inner value in a box to make it representable | |
| // | |
| // This means that `List` is trying to include a copy of itself inside it, and this can’t work | |
| // because the size of an `List` is not known in advance. A “naked” `List` in rust is a `value`, | |
| // not a reference. So to have a node in the list reference another, we have to make it a pointer. | |
| // The object referenced by a managed pointer will be boxed, and its lifetime will be managed | |
| // by the garbage collector. | |
| // | |
| // Cons: Tuple struct that wraps an element and a pointer to the next node | |
| Cons(u32, &'a List<'a>), | |
| // Nil: A node that signifies the end of the linked list | |
| Nil, | |
| } | |
| // Methods can be attached to an enum | |
| impl<'a> List<'a> { | |
| // Create an empty list | |
| fn new() -> List<'a> { | |
| // `Nil` has type `List` | |
| Nil | |
| } | |
| // Consume a list, and return the same list with a new element at its front | |
| fn prepend(&'a self, elem: u32) -> List<'a> { | |
| // `Cons` also has type List | |
| Cons(elem, &self) | |
| } | |
| // Return the length of the list | |
| fn len(&self) -> u32 { | |
| // `self` has to be matched, because the behavior of this method | |
| // depends on the variant of `self` | |
| // `self` has type `&List`, and `*self` has type `List`, matching on a | |
| // concrete type `T` is preferred over a match on a reference `&T` | |
| match *self { | |
| // Can't take ownership of the tail, because `self` is borrowed; | |
| // instead take a reference to the tail | |
| Cons(_, ref tail) => 1 + tail.len(), | |
| // Base Case: An empty list has zero length | |
| Nil => 0 | |
| } | |
| } | |
| // Return representation of the list as a (heap allocated) string | |
| fn stringify(&self) -> String { | |
| match *self { | |
| Cons(head, ref tail) => { | |
| // `format!` is similar to `print!`, but returns a heap | |
| // allocated string instead of printing to the console | |
| format!("{}, {}", head, tail.stringify()) | |
| }, | |
| Nil => { | |
| format!("Nil") | |
| }, | |
| } | |
| } | |
| } | |
| fn main() { | |
| let init: Vec<u32> = vec![2,3,5,7,11,13,17,19]; | |
| // Create an empty linked list | |
| let list = List::new(); | |
| for &x in init.iter() { | |
| // We can create a new node just fine, BUT | |
| // node_node depends on borrowing list, | |
| // so assigning to list would corrupt | |
| // new_node. | |
| let new_node = list.prepend(x); | |
| // Therefore Rust won't let us assign anything | |
| // into list while new_node exists. | |
| // Uncomment the line below to see the error | |
| // list = new_node; | |
| // And new_node ceases to exist at the end | |
| // of the loop, which undoes the prepend. | |
| } | |
| // This makes it so we can't add anything to | |
| // list via a loop. | |
| // Show the final state of the list | |
| println!("linked list has length: {}", list.len()); | |
| println!("{}", list.stringify()); | |
| } |
This file contains hidden or 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
| fn foo(arg1: &str, arg2: &str) { | |
| match (arg1, arg2) { | |
| (_, "hello") => println!("hello world"), | |
| ("foo", _) => println!("foo bar"), | |
| _ => println!("neither"), | |
| } | |
| } | |
| fn main() { | |
| foo("", "hello"); | |
| foo("foo", ""); | |
| foo("foo", "hello"); | |
| foo("", ""); | |
| } |
This file contains hidden or 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
| fn multi_by_2(n: u32) -> u32 { | |
| if n == 1 { | |
| 1 | |
| } else { | |
| multi_by_2(n -1) * 2 | |
| } | |
| } | |
| fn main() { | |
| println!("{}", multi_by_2(7)); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment