Rust Borrow和AsRef的區別


Rust Borrow和AsRef的區別


AsRef/AsRefMutBorrow/BorrowMut具有相似的借語義, 但他們有如下的不同;

  • 任何類型T都實現了(blanket impl)Borrowtrait, 即Rust中任何實例都是可以被借用(&/&mut)的(當然這里任何是指滿足語法語義規則的任何, 比如該實例沒有其被其它實例&mut借用). 而AsRef只是實現了滿足實現了AsRef<U>的類型&T&U的轉換. 源碼如下:;
///////////////////////////////////Borrow
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for T {
    fn borrow(&self) -> &T {
        self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> BorrowMut<T> for T {
    fn borrow_mut(&mut self) -> &mut T {
        self
    }
}

/////////////////////////////////// AsRef
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized, U: ?Sized> AsRef<U> for &T
where
    T: AsRef<U>,
{
    fn as_ref(&self) -> &U {
        <T as AsRef<U>>::as_ref(*self)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized, U: ?Sized> AsRef<U> for &mut T
where
    T: AsRef<U>,
{
    fn as_ref(&self) -> &U {
        <T as AsRef<U>>::as_ref(*self)
    }
}
  • Borrow還有一個潛在的語義是: 如果某個類型實現了Hash/Eq/Ord, 那么在Borrow實例上的Hash/Eq/Ord操作應該和該類型實例上的Hash/Eq/Ord操作是等效的, 如HashMap上的get接口實現對K的類型約束. 根據該潛在的語義, 如果只是借用某個結構struct中的某個域, 應該實現AsRef而不是Borrow;

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for &T {
    fn borrow(&self) -> &T {
        &**self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Borrow<T> for &mut T {
    fn borrow(&self) -> &T {
        &**self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> BorrowMut<T> for &mut T {
    fn borrow_mut(&mut self) -> &mut T {
        &mut **self
    }
}

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM