W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
標(biāo)準(zhǔn)庫提供了一個(gè)特殊的特征,Deref。它通常用于重載 * ,取消引用運(yùn)算符:
use std::ops::Deref;
struct DerefExample<T> {
value: T,
}
impl<T> Deref for DerefExample<T> {
type Target = T;
fn deref(&self) -> &T {
&self.value
}
}
fn main() {
let x = DerefExample { value: 'a' };
assert_eq!('a', *x);
}
這用于編寫自定義指針類型。然而,有一個(gè)與 Deref 相關(guān)的語言特征:‘deref 強(qiáng)制轉(zhuǎn)換’。規(guī)則是這樣的:如果你有一個(gè)類型 U,它實(shí)現(xiàn) Deref<Target=T>
,&U 的值自動(dòng)強(qiáng)制轉(zhuǎn)換為 &T。這里有一個(gè)例子:
fn foo(s: &str) {
// borrow a string for a second
}
// String implements Deref<Target=str>
let owned = "Hello".to_string();
// therefore, this works:
foo(&owned);
在一個(gè)值前使用 & 需要一個(gè)引用。所以 owned 是一個(gè) String,&owned 是一個(gè) &String,并且由于 impl Deref<Target=str> for String
,&String 參考傳入函數(shù) foo() 的 &str。
就這樣。這條規(guī)則是 Rust 為你自動(dòng)轉(zhuǎn)換的少有的幾處之一,但它增加了很大的靈活性。例如,類型 Rc<T>
實(shí)現(xiàn) Deref<Target=T>
,所以它的工作原理如下:
use std::rc::Rc;
fn foo(s: &str) {
// borrow a string for a second
}
// String implements Deref<Target=str>
let owned = "Hello".to_string();
let counted = Rc::new(owned);
// therefore, this works:
foo(&counted);
所有我們所做的就是把我們的 String 封裝到 Rc<T>
。但是我們現(xiàn)在可以把 Rc<String>
傳到任何有 String 的地方。foo 的聲明并沒有改變,但能實(shí)現(xiàn)與其它類型一樣的功能。這個(gè)例子有兩個(gè)轉(zhuǎn)換:Rc<String>
轉(zhuǎn)換為 String,然后 String 轉(zhuǎn)換為 &str。Rust 會(huì)這樣做盡可能多的次數(shù)直到類型匹配?! ?/p>
標(biāo)準(zhǔn)庫提供的另一個(gè)很常見的實(shí)現(xiàn)是:
fn foo(s: &[i32]) {
// borrow a slice for a second
}
// Vec<T> implements Deref<Target=[T]>
let owned = vec![1, 2, 3];
foo(&owned);
向量可以取消對(duì)程序片的引用。
Deref 調(diào)用方法時(shí)也起作用。換句話說,Rust 有相同的兩件事:
struct Foo;
impl Foo {
fn foo(&self) { println!("Foo"); }
}
let f = Foo;
f.foo();
盡管 f 不是引用,但是函數(shù) foo 中傳入 &self 就會(huì)起作用。這是因?yàn)檫@些東西是相同的:
f.foo();
(&f).foo();
(&&f).foo();
(&&&&&&&&f).foo();
&&&&&&&&&&&&&&&&Foo
類型的值仍然可以有定義在 Foo 上的方法,因?yàn)榫幾g器會(huì)插入許多 操作只要程序正確運(yùn)行。因?yàn)樗牟迦?/em> s,就要使用 Deref。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: