added string stuff
This commit is contained in:
+78
@@ -1,5 +1,83 @@
|
|||||||
mod fmt_debug;
|
mod fmt_debug;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
fn takes_string(_s: String) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
fn takes_str_ref(_s: &str) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// yeah, we can do this
|
||||||
|
fn _get_static_str() -> &'static str {
|
||||||
|
"hello"
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
fmt_debug::test_report();
|
fmt_debug::test_report();
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
println!("Hello, world!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user