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

时间:2015-06-01 05:55:18

标签: pointers rust

以下是Deref example from The Rust Programming Language,除了我添加了另一个断言。

为什么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");
}

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

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)

1 个答案:

答案 0 :(得分:9)

首先,让我们列出您的具体示例的通用类型:'a'char,所以我们有:

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

    fn deref(&self) -> &char {
        &self.value
    }
}

值得注意的是,deref的返回类型是引用char。因此,当您仅使用x.deref()时,结果为&char而不是char,这不足为奇。请记住,此时deref只是另一种常规方法 - 它只是隐式调用某些语言提供的特殊语法的 part 。例如,*x会调用deref并在适用时取消引用结果。 x.char_method()fn_taking_char(&x)也会多次致电deref,然后对结果采取进一步措施。

为什么deref会返回一个开头的引用,你问?那不是通告吗?嗯,不,它不是循环的:它减少库定义的智能指针到内置类型&T,编译器已经知道如何取消引用。通过返回引用而不是值,您可以避免复制/移动(这可能并不总是可行!)并允许&*x(或&x强制执行时)引用实际 char DerefExample持有而不是临时副本。

另见: