added more strings and todos
This commit is contained in:
+68
-32
@@ -1,3 +1,4 @@
|
|||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
// when a String is passed to this function a move occurs:
|
// when a String is passed to this function a move occurs:
|
||||||
// BUT only the stack allocation (ptr, len, cap) is copied over
|
// BUT only the stack allocation (ptr, len, cap) is copied over
|
||||||
@@ -10,6 +11,8 @@ fn takes_string(_s: String) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// You can do this, but you probably want &str
|
||||||
|
// UNLESS you want `&mut String`
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn takes_string_ref(_s: &String) {
|
fn takes_string_ref(_s: &String) {
|
||||||
|
|
||||||
@@ -27,7 +30,7 @@ fn takes_string_ref(_s: &String) {
|
|||||||
// Why is this a problem?
|
// Why is this a problem?
|
||||||
// rust doesn't know how much space to allocate for the variable
|
// rust doesn't know how much space to allocate for the variable
|
||||||
//
|
//
|
||||||
// str inactuality is the raw (UTF-8) bytes, not a container
|
// str in actuality is the raw (UTF-8) bytes, not a container
|
||||||
// fn takes_str(s: str) { }
|
// fn takes_str(s: str) { }
|
||||||
|
|
||||||
// this is fine because now the variable is a fat pointer: pointer + length
|
// this is fine because now the variable is a fat pointer: pointer + length
|
||||||
@@ -42,42 +45,75 @@ fn _get_static_str() -> &'static str {
|
|||||||
"hello"
|
"hello"
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
// The #[cfg(test)] annotation on the tests module tells Rust to compile
|
||||||
fn test_string() {
|
// and run the test code only when you run cargo test, not when you run cargo build
|
||||||
let s = String::new(); // no heap allocation until we add characters (capacity > 0)
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*; // need access to functions above
|
||||||
|
|
||||||
// let s_r: str; // ERROR: size not known at compile time
|
#[test]
|
||||||
let _s_rr: &str; // allowed
|
fn test_string() {
|
||||||
let _s_rrr: &String; // allowed
|
let s = String::new(); // no heap allocation until we add characters (capacity > 0)
|
||||||
|
|
||||||
takes_string_ref(&s);
|
// let s_r: str; // ERROR: size not known at compile time
|
||||||
takes_string_ref(&s); // works because the string was not moved in first call
|
let _s_rr: &str; // allowed
|
||||||
|
let _s_rrr: &String; // allowed
|
||||||
|
|
||||||
let ss = String::from("1"); // one heap allocation!
|
takes_string_ref(&s);
|
||||||
takes_string(ss); // move occurs here
|
takes_string_ref(&s); // works because the string was not moved in first call
|
||||||
// takes_string(ss); // ERROR: use of moved value here
|
|
||||||
// takes_string_ref(&ss); // ERROR: borrow of moved value here
|
|
||||||
|
|
||||||
let sss = String::new();
|
let ss = String::from("1"); // one heap allocation!
|
||||||
// deref coersion:
|
takes_string(ss); // move occurs here
|
||||||
// because String implements the trait Deref<Target = str>
|
// takes_string(ss); // ERROR: use of moved value here
|
||||||
takes_str_ref(&sss);
|
// takes_string_ref(&ss); // ERROR: borrow of moved value here
|
||||||
// *sss dereferences the String into its underlying str
|
|
||||||
takes_str_ref(&*sss); // same as this!
|
|
||||||
takes_str_ref(sss.as_ref()); // and this!
|
|
||||||
|
|
||||||
let s4 = String::from("string4");
|
let sss = String::new();
|
||||||
//let s4_slice = s4[0..]; // again we hit no size problem at compile time
|
// deref coersion:
|
||||||
let _s4_slice = &s4[0..]; // but this works, because the &str has the length!
|
// because String implements the trait Deref<Target = str>
|
||||||
|
takes_str_ref(&sss);
|
||||||
|
// *sss dereferences the String into its underlying str
|
||||||
|
takes_str_ref(&*sss); // same as this!
|
||||||
|
takes_str_ref(sss.as_ref()); // and this!
|
||||||
|
|
||||||
// literals
|
let s4 = String::from("string4");
|
||||||
// &'static str is held onto by &str:
|
//let s4_slice = s4[0..]; // again we hit no size problem at compile time
|
||||||
// that's the programs read-only binary
|
let _s4_slice = &s4[0..]; // but this works, because the &str has the length!
|
||||||
let s_lit = "easy as pie, right?";
|
|
||||||
let _s_lit2 : &str = "easy as pie, right?"; // same, data not copied, we just point to it
|
|
||||||
let _s5 = String::from("literal is copied to heap"); // data copied to heap
|
|
||||||
let _s6 = String::from(s_lit); //underlying data copied to heap
|
|
||||||
|
|
||||||
// todo: Cow
|
// literals
|
||||||
|
// &'static str is held onto by &str:
|
||||||
|
// that's the programs read-only binary
|
||||||
|
let s_lit = "easy as pie, right?";
|
||||||
|
let _s_lit2 : &str = "easy as pie, right?"; // same, data not copied, we just point to it
|
||||||
|
let _s5 = String::from("literal is copied to heap"); // data copied to heap
|
||||||
|
let _s6 = String::from(s_lit); //underlying data copied to heap
|
||||||
|
|
||||||
|
// Box<str> is owned, heap allocated, fixed size, immutable
|
||||||
|
// where as `&str` is borrowed view, linked to source, immutable
|
||||||
|
// both have (ptr, len) -> underlying mem
|
||||||
|
let _s7 : Box<str> = "hello".into();
|
||||||
|
|
||||||
|
// Rc<str> (single-threaded reference counting)
|
||||||
|
// HEAP memory layout:
|
||||||
|
// * counter (strong)
|
||||||
|
// * counter (weak)
|
||||||
|
// * len
|
||||||
|
// * data
|
||||||
|
// STACK memory:
|
||||||
|
// * ptr
|
||||||
|
// * len
|
||||||
|
//
|
||||||
|
// Why are there two lengths?
|
||||||
|
let rc_str : Rc<str> = Rc::from("rc_str");
|
||||||
|
// let rc_str2 : Rc<str> = rc_str; // this moves
|
||||||
|
let rc_str2 : Rc<str> = rc_str.clone(); // copy ptr, increment counter
|
||||||
|
println!("printing {}", rc_str);
|
||||||
|
println!("printing {}", rc_str);
|
||||||
|
println!("printing {}", rc_str2);
|
||||||
|
|
||||||
|
// todo: Arc<str>
|
||||||
|
// todo: Cow
|
||||||
|
// todo: byte strings: &[u8] and Vec<u8>
|
||||||
|
// todo: Os & platform strings: OsStr & OsString, Path & PathBuf
|
||||||
|
// todo: ffi strings: CString & CStr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user