99re热视频这里只精品,久久久天堂国产精品女人,国产av一区二区三区,久久久精品成人免费看片,99久久精品免费看国产一区二区三区

'Deref'強制轉(zhuǎn)換

2018-08-12 22:03 更新

'Deref'強制轉(zhuǎn)換

標準庫提供了一個特殊的特征,Deref。它通常用于重載 * ,取消引用運算符:

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);
}

這用于編寫自定義指針類型。然而,有一個與 Deref 相關(guān)的語言特征:‘deref 強制轉(zhuǎn)換’。規(guī)則是這樣的:如果你有一個類型 U,它實現(xiàn) Deref<Target=T>,&U 的值自動強制轉(zhuǎn)換為 &T。這里有一個例子:

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);

在一個值前使用 & 需要一個引用。所以 owned 是一個 String,&owned 是一個 &String,并且由于 impl Deref<Target=str> for String,&String 參考傳入函數(shù) foo() 的 &str。

就這樣。這條規(guī)則是 Rust 為你自動轉(zhuǎn)換的少有的幾處之一,但它增加了很大的靈活性。例如,類型 Rc<T> 實現(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 的聲明并沒有改變,但能實現(xiàn)與其它類型一樣的功能。這個例子有兩個轉(zhuǎn)換:Rc<String> 轉(zhuǎn)換為 String,然后 String 轉(zhuǎn)換為 &str。Rust 會這樣做盡可能多的次數(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);

向量可以取消對程序片的引用。

Deref 和方法調(diào)用

Deref 調(diào)用方法時也起作用。換句話說,Rust 有相同的兩件事:

struct Foo;

impl Foo {
fn foo(&self) { println!("Foo"); }
}

let f = Foo;

f.foo();

盡管 f 不是引用,但是函數(shù) foo 中傳入 &self 就會起作用。這是因為這些東西是相同的:

f.foo();
(&f).foo();
(&&f).foo();
(&&&&&&&&f).foo();

&&&&&&&&&&&&&&&&Foo 類型的值仍然可以有定義在 Foo 上的方法,因為編譯器會插入許多 操作只要程序正確運行。因為它的插入 s,就要使用 Deref。

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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號