为什么Deref :: deref本身的返回类型是引用?

时间:2015-07-25 08:52:32

标签: pointers reference rust

我正在阅读Rust Deref特性的文档:

pub trait Deref {
    type Target: ?Sized;
    fn deref(&self) -> &Self::Target;
}

deref函数的类型签名对我来说似乎是违反直觉的;为什么返回类型是引用?如果引用实现了这个特性,那么它们可以被解除引用,这会产生什么影响呢?

我能提出的唯一解释是,引用不会实现Deref,但会被视为&#34;原始可解除引用&#34;。但是,如何编写适用于任何可解除引用类型的多态函数,包括Deref<T>&T

2 个答案:

答案 0 :(得分:9)

  

引用并未实现Deref

您可以看到all the types that implement Deref&T位于该列表中:

impl<'a, T> Deref for &'a T where T: ?Sized

非显而易见的是,当您使用*运算符实现Deref时,会应用语法糖。看看这个小例子:

use std::ops::Deref;

fn main() {
    let s: String = "hello".into();
    let _: () = Deref::deref(&s);
    let _: () = *s;
}
error[E0308]: mismatched types
 --> src/main.rs:5:17
  |
5 |     let _: () = Deref::deref(&s);
  |                 ^^^^^^^^^^^^^^^^ expected (), found &str
  |
  = note: expected type `()`
             found type `&str`

error[E0308]: mismatched types
 --> src/main.rs:6:17
  |
6 |     let _: () = *s;
  |                 ^^ expected (), found str
  |
  = note: expected type `()`
             found type `str`

deref的显式调用会返回&str,但运算符*会返回str。它更像是在调用*Deref::deref(&s),忽略隐含的无限递归。

Xirdus is correct in saying

  

如果deref返回一个值,它将无用,因为它总是会移出,或者语义与其他所有函数完全不同

虽然&#34;无用&#34;有点强烈;它对于实现Copy的类型仍然有用。

另见:

答案 1 :(得分:3)

编译器只知道如何取消引用&amp; -pointers - 但它也知道实现Deref trait的类型有一个deref()方法,可用于获取对给定内容的适当引用宾语。如果你取消引用一个对象,你实际做的是先获取引用,然后才取消引用它。

如果deref()返回一个值,它将无用,因为它总是会移出,或者语义与其他不好的函数完全不同。