Skip to content

Instantly share code, notes, and snippets.

@bootandy
Last active April 3, 2018 13:44
Show Gist options
  • Save bootandy/37e84b1b5738f85a52c2c4d1d837218e to your computer and use it in GitHub Desktop.
Save bootandy/37e84b1b5738f85a52c2c4d1d837218e to your computer and use it in GitHub Desktop.
sample rust code
pub fn how_to_loop_round_a_vec(tokens : &[reader::Token]) {
let ti = tokens[1..].iter();
let mut new_list = vec![to_add];
// If you do not specify an iter() in a loop then into_iter() is used which consumes the vec
for nxt_token in ti {
new_list.push(
match nxt_token {
&reader::Token::List(ref list) => apply_sym(None, None, &list, func_map),
&_ => nxt_token.clone()
}
);
}
}
// A type of function!
#![feature(core_intrinsics)] // This line needs to go in src/main.rs or src/lib.rs
use std;
fn print_type_of<T>(_: T) {
println!("{}", unsafe { std::intrinsics::type_name::<T>() });
}
// A left pad see: https://doc.rust-lang.org/std/fmt/
fn padme() {
let s = format!("{:>width$}", "leftpad me", width=15);
println!("{:?}", s)
}
// Copy trait allows us to automatically copy an object so things 'just work'
//http://manishearth.github.io/rust-internals-docs/core/marker/trait.Copy.html
/* try! macro
try! is used for error handling.
It takes something that can return a Result<T, E>, and gives T if it’s a Ok<T>,
and returns with the Err(E) if it’s that. Like this:
Edit 'try!' is old. It is replaced by '?' (Elvis operator)
The difference between '.unwrap()' and '?' is that unwrap() will panic where as ? returns an Err object
*/
use std::fs::File;
fn foo() -> std::io::Result<()> {
let f = try!(File::create("foo.txt"));
Ok(())
}
extern crate regex;
macro_rules! regex {
($e:expr) => (regex::Regex::new($e).unwrap())
}
pub fn how_2_regex(s_in: &str) {
let mut s = &s_in[0..];
let comment = regex!(r###"^[\s,]*(;.*)$"###);
// Need to know where matched and if there were multiple matches
if let Some(the_comment) = comment.captures(s) {
s = &s[the_comment.get(1).unwrap().end()..];
}
// Just the matching str please:
if let Some(the_comment2) = comment.find(s) {
s = &the_comment2.as_str();
}
}
// https://doc.rust-lang.org/regex/regex/struct.Regex.html#method.find
pub fn how_2_accept_string_and_str() {
let person = Person::new("Herman");
let person2 = Person::new("Herman".to_string());
// Count number of chars in a string:
let count_char = person.name.matches("n").count();
}
struct Person {
name: String,
}
impl Person {
fn new<S: Into<String>>(name: S) -> Person {
Person { name: name.into() }
}
}
// match alternative: if_chain!
fn match_on_node(arg) {
match arg.node {
TyRptr(_, MutTy { ref ty, .. }) => {
eprintln!("found ty: {:?}", ty);
},
_ => (),
};
if_chain! {
if let TyRptr(ref ty) = arg.node;
// can put many if lets here, each dependant on previous one with ; separaters.
then {
eprintln!("found ty: {:?}", ty);
}
}
}
// Cast basic types to_string
fn _format_type<T: ToString>(t: Option<T>) -> String {
match t {
None => "Null".to_string(),
Some(x) => x.to_string()
}
}
fn main_to_str() {
println!("{}", _format_type(Some("34")));
println!("{}", _format_type(Some(34)));
println!("{}", _format_type(Some(3.4)));
println!("{}", _format_type::<u8>(None));
}
fn slice_and_join(s: String) {
let mut v: Vec<&str> = s.split("/").collect();
let result = v[0..(v.len() - 1)].join("/");
}
// How to copy part of an object and return a sub part instead.
pub fn create_v() -> Vec<Vec<i32>> {
vec![ vec![1,2], vec![2,3] ]
}
pub fn create<'l>() -> Vec<i32> {
let mut v = create_v();
let b = std::mem::replace(&mut v[0], vec![]);
println!("{:?}", v);
b
}
pub fn create_array_with_tuple() {
// For some reason arrays with tuples need their length explicitly specified at compiletime - hence '; 2'
let units: [(i32,i32); 2] = [(1, 2), (3, 4)];
for &(u, v) in &units {
// use u,v
}
}
// Iterators
// Creates a consuming iterator, that is, one that moves each value out of the vector (from start to end).
// The vector cannot be used after calling this.
// into_iter(self) -> IntoIter<T>
// iter().peekable() // Creates peekable iter Note: peek() still modifies underlying iter as this is just a wrapper
pub fn use_a_filter() {
let v = vec![1,2,30];
let x = xs.clone();
//This can build a new vec as the old one is consumed
let v2 :Vec<i32> = v.into_iter().filter(|&n| n < 17).collect();
// This only creates a reference to the old 'x' vec as x is still available
let x2 :Vec<&i32> = x.iter().filter(|&n| {n >&2} ).collect();
println!("{:?}", v2);
println!("{:?}", x2);
// With &some_vector into_iter() is assumed.
for row in &x2 {
println!("{:?}", row);
}
// Convert from HashMap -> Vec and back again
let mut func_map = HashMap::new();
func_map.insert(2, 4);
let lst :Vec<(i32,i32)> = func_map.iter().map(|(a, b)| {(*a, *b)}).collect();
let m: HashMap<_, _> = lst.into_iter().collect();
println!("{:?}", m);
// How to take a value from a hashmap and update it fixes: "immutable borrow occurs here"
//https://www.reddit.com/r/rust/comments/2zcvn3/hashmaps_and_pattern_matching_mutability_confusion/
// loop iterate thru a tuple:
for it in test_data.into_iter() {
println!("{} {}", it.0.clone(), it.1);
}
}
// Merge several vectors together / fold vectors
fn merge() {
let v1 = vec![1,2,3];
let v2 = vec![2,3,4];
let v3 = vec![4,5,6];
let vs = vec![v1,v2,v3];
let vend :Vec<u64> = vs.iter().fold(vec![], |mut a, b| { a.extend(b); a } );
}
// This custom iterator created to deal with Errors nested inside Results.
// Type: Result<Iter<Result<Iter<_>>>> -> converts to-> Result<Iter<Iter<_>>>
// Also resolves 'do not know size at compile time compilation error'
pub struct PanicLines(Lines<BufReader<File>>);
impl Iterator for PanicLines {
type Item = String;
fn next(&mut self) -> Option<String> {
match self.0.next() {
None => None,
Some(r) => Some(r.expect("failed to read file")),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
/// Clippy: To run against local clippy see https://github.com/rust-lang-nursery/rust-clippy and use:
/// cargo build --features=clippy
/// Mutable mess:
// def f(v :Object) - pass v into f. v is no longer owned by caller.
// def f(mut v :Object) - pass v into f. v is no longer owned by caller. And we can point v at a different object
// def f(v :&Object) - pass reference to v into f. v is still accessable by caller
// def f(v :&mut Object) - pass reference to v into f. v is still accessable by caller. We can change the values of v
// def f(mut v :&mut Object) - pass reference to v into f. v is still accessable by caller. We can change the values of v.
// Inside this function we can point v to a different object - although this will not change the caller's reference.
def f(mut v : &mut Vec<i32>) {
v.push(0); // Yep we modify the original v
v = vec![0] // we update our local copy to point at new object
} // here vec![0] is deallocated and our caller will have the original v with 0 appended to it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment