ref 키워드는 패턴 매칭 과정에서 값의 참조를 만들어 해당 값을 이동(move)하는 대신 빌려오도록(bind by reference) 하는 데 사용됩니다.
패턴 매칭에 관해서는 매칭 여부에 영향을 주지 않으며, 값이 어떻게 매치되는지만 제어합니다.
기본적으로, match 문은 사용 가능한 모든 값을 소비합니다.
따라서 값의 소유권이 필요하지 않은 경우에도 문제가 될 수 있습니다.
let maybe_name = Some(String::from("Alice"));
// 변수 'maybe_name'이 여기서 소비됩니다...
match maybe_name {
Some(n) => println!("Hello, {}", n),
_ => println!("Hello, world"),
}
// ... 이제 사용할 수 없습니다.
println!("Hello again, {}", maybe_name.unwrap_or("world".into()));
ref 키워드를 사용하면 값이 빌려온 것이지만 이동하지 않으므로, match 문 이후에도 사용할 수 있습니다.
let maybe_name = Some(String::from("Alice"));
// `ref`를 사용하여 값이 빌려오고 이동하지 않습니다...
match maybe_name {
Some(ref n) => println!("Hello, {}", n),
_ => println!("Hello, world"),
}
// ... 그래서 여기에서 사용할 수 있습니다!
println!("Hello again, {}", maybe_name.unwrap_or("world".into()));
&와 ref의 차이점:
&는 패턴이 객체에 대한 참조를 기대함을 나타냅니다. 따라서 &는 해당 패턴의 일부분입니다. &Foo는 Foo와 다른 객체와 매치됩니다.ref는 값의 참조를 얻기를 원함을 나타냅니다. 매치 대상이 아닙니다. Foo(ref foo)는 Foo(foo)와 동일한 객체와 매치됩니다.우측 예제에서는 String 타입을 사용하고 있습니다.
ref 키워드를 사용하지 않을 경우, if let 구문에서 소유권이 이동하게 되어 이후에 x를 사용할 수 없게 됩니다.
그러나 ref 키워드를 사용함으로써 소유권이 이동하지 않고 참조가 생성되어 이후에도 x를 사용할 수 있습니다.