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

Why is the return type of Deref::deref itself a reference?

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

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

Deref函数的类型签名对我来说似乎违反直觉。 为什么返回类型是引用? 如果引用实现了此特性,因此可以将其取消引用,这将产生什么影响?

我能提出的唯一解释是,引用未实现Deref,但被认为是"原始可解除引用"。 但是,如何编写适用于任何可解除引用的类型(包括Deref< T >&T)的多态函数呢?


that references don't implement Deref

您可以看到实现Deref的所有类型,并且&T在该列表中:

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

不明显的是,当您将*运算符与实现Deref的东西一起使用时,会应用语法糖。看看这个小例子:

1
2
3
4
5
6
7
use std::ops::Deref;

fn main() {
    let s: String ="hello".into();
    let _: () = Deref::deref(&s);
    let _: () = *s;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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的说法正确

If deref returned a value, it would either be useless because it would always move out, or have semantics that drastically differ from every other function

尽管"无用"有点强;它对于实现Copy的类型仍然有用。

也可以看看:

  • 为什么对Deref :: deref的结果进行断言会因类型不匹配而失败?

请注意,以上所有内容对于IndexIndexMut同样有效。


编译器仅知道如何取消引用&指针-但它也知道实现Deref特征的类型具有deref()方法,该方法可用于获取对给定对象内部内容的适当引用。如果取消引用对象,则实际要做的是先获取引用,然后再取消引用。

如果deref()返回一个值,则它要么会因为总是移出而变得无用,要么具有与其他所有函数完全不同的语义,这不是很好。