C++에서 참조는 참조 대상과 같은 타입니다.
int data = 10;
int& data_ref = data;
cout << data_ref << endl;
하지만 &를 사용한다고 해서 C++ 처럼 참조 대상과 같은 타입이 아니다.
let mut foo = 42 as i32;
let foo_ref = &mut foo;
//error 발생 foo_ref는 변수가 아니다. &mut i32(변경 가능한 i32 참조) 이다.
foo_ref = 13;
println!("{}", foo);
마치 C++의 포인터를 반환 하는 것과 비슷한 모습니다.
정상적으로 처리하기 위해서는 *
를 사용하여 역참조를 해야 한다.
*foo_ref = 13;
println!("{}", foo);
역참조를 사용하여 값의 복사본도 가져올 수 있다(복사 가능한 경우에만)
fn main() {
let mut foo = 42 as i32;
let foo_ref = &mut foo;
let bar = *foo_ref;//복사 발생
*foo_ref = 13;
println!("{}", foo);//13
println!("{}", bar);//42
}
&
와 *
를 반드시 한번만 사용 하라는 법은 없다.
let a: i32 = 42;
let ref_ref_ref_a: &&&i32 = &&&a;
let ref_a: &i32 = **ref_ref_ref_a;
let b: i32 = *ref_a;
i32는 Copy trait을 구현하는 기본 자료형이기 때문에, stack에 있는 변수 a의 바이트들은 변수 b의 바이트들로 복사 된다.
한가지 염두해 두어야 할 점은 구조체에서 참조는 참조 대상과 같은 방식으로 값 접근이 가능 하다.
struct Foo {
x: i32,
}
fn main() {
let foo = Foo {x: 42};
let f = &&&foo;
println!("{}", foo.x);
println!("{}", f.x);
//println!("{}", (***ref_ref_ref_f).value); 자동 변환
}