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

cor*_*zza 11 pointers reference rust

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

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

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

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

She*_*ter 11

引用没有实现 Deref

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

impl<'a, T> Deref for &'a T where T: ?Sized
Run Code Online (Sandbox Code Playgroud)

不明显的是,当你使用*带有实现的东西的运算符时,会应用语法糖Deref.看看这个小例子:

use std::ops::Deref;

fn main() {
    let s: String = "hello".into();
    let _: () = Deref::deref(&s);
    let _: () = *s;
}
Run Code Online (Sandbox Code Playgroud)
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`
Run Code Online (Sandbox Code Playgroud)

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

Xirdus说得对

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

虽然"无用"有点强烈; 它对于实现的类型仍然有用Copy.

也可以看看:


Xir*_*dus 5

编译器只知道如何取消引用 & 指针 - 但它也知道实现Dereftrait 的类型有一个deref()方法,可用于获取对给定对象内某些内容的适当引用。如果你解引用一个对象,你实际做的是首先获取引用,然后才解引用它。

如果deref()返回一个值,它要么是无用的,因为它总是会移出,要么具有与其他不好的函数截然不同的语义。