NeuroWhAI의 잡블로그

[Rust] AsRef와 Borrow trait의 차이 본문

개발 및 공부/언어

[Rust] AsRef와 Borrow trait의 차이

NeuroWhAI 2019. 1. 23. 20:24


Rust 표준 라이브러리에 있는 AsRefBorrow 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


  1. 모든 타입 T는 자기 자신의 레퍼런스를 반환하는 Borrow trait을 구현하고 있습니다. [본문으로]


Comments