'Deref'強(qiáng)制轉(zhuǎn)換

2018-08-12 22:03 更新

'Deref'強(qiáng)制轉(zhuǎn)換

標(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)用

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。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)