moved string stuff to it's own file

This commit is contained in:
2026-04-25 06:41:01 -04:00
committed by edgul
parent 591b122c81
commit 0c9a7ec030
2 changed files with 85 additions and 2 deletions
+2 -2
View File
@@ -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!");
}
+83
View File
@@ -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
}