Last active
April 3, 2018 13:44
-
-
Save bootandy/37e84b1b5738f85a52c2c4d1d837218e to your computer and use it in GitHub Desktop.
sample rust code
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
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