moved string stuff to it's own file
This commit is contained in:
+2
-2
@@ -1,3 +1,4 @@
|
||||
mod string;
|
||||
mod fmt_debug;
|
||||
|
||||
// when a String is passed to this function a move occurs:
|
||||
@@ -41,6 +42,7 @@ fn _get_static_str() -> &'static str {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
fmt_debug::test_report();
|
||||
|
||||
let s = String::new(); // no heap allocation until we add characters (capacity > 0)
|
||||
@@ -78,6 +80,4 @@ fn main() {
|
||||
let _s6 = String::from(s_lit); //underlying data copied to heap
|
||||
|
||||
// todo: Cow
|
||||
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
// when a String is passed to this function a move occurs:
|
||||
// BUT only the stack allocation (ptr, len, cap) is copied over
|
||||
// AND the underlying heap is preserved, without copy
|
||||
//
|
||||
// Why do we call it a "move"?
|
||||
// A move indicates ownership transfer, not data transfer
|
||||
#[allow(dead_code)]
|
||||
fn takes_string(_s: String) {
|
||||
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn takes_string_ref(_s: &String) {
|
||||
|
||||
}
|
||||
|
||||
// Compilation error and warning:
|
||||
// rustc: the size for values of type `str` cannot be known at compilation time
|
||||
// the trait `Sized` is not implemented for `str` [E0277]
|
||||
// rustc: function arguments must have a statically known size,
|
||||
// borrowed types always have a known size: `&` [E0277]
|
||||
//
|
||||
// Ok, so rust is an unsized type,
|
||||
// and compiler requires sized types for function params at compile time
|
||||
//
|
||||
// Why is this a problem?
|
||||
// rust doesn't know how much space to allocate for the variable
|
||||
//
|
||||
// str inactuality is the raw (UTF-8) bytes, not a container
|
||||
// fn takes_str(s: str) { }
|
||||
|
||||
// this is fine because now the variable is a fat pointer: pointer + length
|
||||
// it's the length aspect that makes us abot to work on the str
|
||||
#[allow(dead_code)]
|
||||
fn takes_str_ref(_s: &str) {
|
||||
|
||||
}
|
||||
|
||||
// yeah, we can do this
|
||||
fn _get_static_str() -> &'static str {
|
||||
"hello"
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string() {
|
||||
let s = String::new(); // no heap allocation until we add characters (capacity > 0)
|
||||
|
||||
// let s_r: str; // ERROR: size not known at compile time
|
||||
let _s_rr: &str; // allowed
|
||||
let _s_rrr: &String; // allowed
|
||||
|
||||
takes_string_ref(&s);
|
||||
takes_string_ref(&s); // works because the string was not moved in first call
|
||||
|
||||
let ss = String::from("1"); // one heap allocation!
|
||||
takes_string(ss); // move occurs here
|
||||
// takes_string(ss); // ERROR: use of moved value here
|
||||
// takes_string_ref(&ss); // ERROR: borrow of moved value here
|
||||
|
||||
let sss = String::new();
|
||||
// deref coersion:
|
||||
// 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!
|
||||
|
||||
let s4 = String::from("string4");
|
||||
//let s4_slice = s4[0..]; // again we hit no size problem at compile time
|
||||
let _s4_slice = &s4[0..]; // but this works, because the &str has the length!
|
||||
|
||||
// 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
|
||||
|
||||
// todo: Cow
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user