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

aus*_*day 12 pointers rust

以下是Rust编程语言中Deref示例,除了我添加了另一个断言.

为什么assert_eqderef平等'a'?为什么我需要*手动调用一次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()); // this is true
    // assert_eq!('a', x.deref()); // this is a compile error
    assert_eq!('a', *x); // this is also true
    println!("ok");
}
Run Code Online (Sandbox Code Playgroud)

如果我取消注释该行,我会收到此错误:

error[E0308]: mismatched types
  --> src/main.rs:18:5
   |
18 |     assert_eq!('a', x.deref());
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected char, found &char
   |
   = note: expected type `char`
              found type `&char`
   = help: here are some functions which might fulfill your needs:
           - .to_ascii_lowercase()
           - .to_ascii_uppercase()
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
Run Code Online (Sandbox Code Playgroud)

小智 9

首先,让我们为您的具体示例说明泛型类型:'a'char,所以我们有:

impl Deref for DerefExample<char> {
    type Target = char;

    fn deref(&self) -> &char {
        &self.value
    }
}
Run Code Online (Sandbox Code Playgroud)

值得注意的是,的返回类型deref是一个参考char.因此,当你使用just时x.deref(),结果是一个&char而不是一个,这应该不足为奇char.请记住,此时deref只是另一种常规方法 - 它只是作为某种语言提供的特殊语法的一部分被隐式调用.*x例如deref,如果适用,将调用和取消引用结果.x.char_method()并且fn_taking_char(&x)还会调用deref多次,然后对结果做更多​​的事情.

deref你问,为什么要返回一个引用开头?那不是通告吗?好吧,不,它不是循环的:它减少了库定义的智能指针到内置类型&T,编译器已经知道如何取消引用.通过返回一个参考,而不是一个值,你避免复制/移动(这可能并不总是可能的!),并允许&*x(或&x当它裹挟)来指代实际 charDerefExample持有,而不是一个临时副本.

也可以看看: