NeuroWhAI의 잡블로그
[Rust] AsRef와 Borrow trait의 차이 본문
Rust 표준 라이브러리에 있는 AsRef와 Borrow trait은 생긴 것이 매우 비슷합니다.
pub trait AsRef<T>
where
T: ?Sized,
{
fn as_ref(&self) -> &T;
}
pub trait Borrow<Borrowed>
where
Borrowed: ?Sized,
{
fn borrow(&self) -> &Borrowed;
}
impl<T> Borrow<T> for T
impl<'_, T, U> AsRef<U> for &'_ T
where
T: AsRef<U> + ?Sized,
U: ?Sized
제너릭 타입 한개와 그 타입의 레퍼런스를 반환하는 메소드 하나를 가지고 있습니다.
똑같죠.
그러나 그 의미와 쓰임새는 다릅니다.
AsRef는 std::convert 모듈에 있고 Borrow는 std::borrow 모듈에 있다는 것만 봐도 그렇죠.
AsRef는 말 그대로 어떤 타입을 다른 타입의 레퍼런스로 변환(convert)하여 쓰기 위한 곳이면 다 쓸 수 있지만
Borrow는 Rust의 소유-빌림(borrow) 관계에 있는 타입들을 전부 동일하게 다루기 위해 쓰입니다.
의미적으로 소유-빌림 관계 속의 데이터는 동일한 것이니까요.
예를 들어 '소유하는 타입'인 String은 Borrow<str>을 구현하여 '빌리는 타입'인 &str를 얻을 수 있게 하고 있으며
이것 덕분에 borrow 메소드로 String과 &str 둘다 &str로 취급하여 의미적으로 동일하게 사용할 수 있습니다.
예를 들어 제너릭 타입 T가 Borrow<str>를 구현하고 있고 여기에서 borrow을 호출하면 무엇이 들어오든 상관없이 &str을 얻어 사용할 수 있다는 것이죠.
(&str에서도 borrow을 호출해서 &str을 얻을 수 있는데 그 이유는 이 글의 3번째 코드 덕분입니다.) 1
정리하면 두 타입이 소유-빌림의 관계에 있으며 의미적으로 동일하게 사용하기 위해서라면 Borrow를 사용하고
그 외에 단순히 어떤 타입에서 다른 타입의 레퍼런스를 얻기 위해, 혹은 어떤 타입들을 공통적인 레퍼런스 타입 하나로 일반화하여 사용하고 싶을 때 AsRef를 사용하면 됩니다.
저도 공부하는 입장이라 틀린 부분이 있을 수 있습니다.
많이 지적 부탁드립니다.
※ 참고
- https://doc.rust-lang.org/std/convert/trait.AsRef.html
- https://doc.rust-lang.org/std/borrow/trait.Borrow.html
- https://github.com/rust-lang/rust/issues/24140
- 모든 타입 T는 자기 자신의 레퍼런스를 반환하는 Borrow
trait을 구현하고 있습니다. [본문으로]
'개발 및 공부 > 언어' 카테고리의 다른 글
[C++] ref-qualified member functions : 값의 종류에 따라 메소드 오버로딩하기 (0) | 2019.02.22 |
---|---|
[C#] Index, Range 구조체와 hat('^') 연산자 (0) | 2019.02.18 |
[Rust] 패턴 매칭 바인딩 모드(Binding Modes) 설명 (0) | 2019.01.20 |
[Rust] panic 감지하여 잡기(catch) (0) | 2019.01.13 |
[Rust] turbofish - 제너릭 타입 지정 문법 (0) | 2019.01.10 |
Comments