s1이 String을 소유
s1: String
h
e
l
l
o
let s1 = String::from("hello");
&s1은 값을 가져가는 것이 아니라, 소유자인 s1을 가리키는 읽기 통로를 만든다. 그래서 함수 호출 뒤에도 원래 값은 그대로 사용할 수 있다.
함수는 길이만 읽으면 되므로 String 자체가 아니라 참조자를 받으면 충분하다.
let s1 = String::from("hello");
let len = calculate_length(&s1);
&s1은 소유권을 가져가지 않는다.
println!("{}", s1);
대여가 끝나면 원래 소유자는 계속 사용할 수 있다.
여러 사람이 읽는 것은 괜찮지만, 쓰는 사람이 있으면 혼자만 접근해야 데이터 경합을 막을 수 있다.
let r1 = &s;
let r2 = &s;
println!("{r1} {r2}");
모두 읽기만 하므로 값이 중간에 바뀔 걱정이 없다.
let r = &mut s;
r.push_str("!");
수정할 수 있지만 같은 값에 대한 다른 참조와 겹치면 안 된다.
let r1 = &s; let r2 = &mut s;
읽는 쪽은 값이 변하지 않는다고 믿기 때문에 컴파일러가 막는다.
참조가 더 이상 쓰이지 않으면 그 뒤에 가변 참조를 만들 수 있다.
let r1 = &s; let r2 = &s;
둘 다 읽기만 하는 참조다.
println!("{r1} {r2}");
이 지점 이후 r1, r2는 더 이상 쓰이지 않는다.
let r3 = &mut s;
읽기 참조와 사용 구간이 겹치지 않으므로 허용된다.
fn dangle() -> &String { ... }
반환된 참조가 사라진 값을 가리키면 컴파일 오류가 난다.