Skip to content

Instantly share code, notes, and snippets.

@bangedorrunt
Last active November 25, 2015 02:30
Show Gist options
  • Save bangedorrunt/a9927c63e5ca8f6e33e4 to your computer and use it in GitHub Desktop.
Save bangedorrunt/a9927c63e5ca8f6e33e4 to your computer and use it in GitHub Desktop.
Rust tips
// 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();
}
}
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());
}
// 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());
}
// 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());
}
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("", "");
}
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