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

2024-03-25

以下是Deref示例来自Rust 编程语言 https://doc.rust-lang.org/book/first-edition/deref-coercions.html除了我添加了另一个断言。

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

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

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

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

值得注意的是,返回类型deref is a 参考 to a char。因此,当您只使用x.deref(),结果是&char而不是一个char。请记住,那时deref只是另一个普通方法 - 它只是隐式调用part某些语言提供的特殊语法。*x,例如,将调用deref并在适用时取消引用结果。x.char_method() and fn_taking_char(&x)也会打电话deref多次,然后根据结果做进一步的事情。

为什么deref您问,首先返回一个引用吗?这不是圆形的吗?嗯,不,它不是圆形的:它reduces库定义的指向内置类型的智能指针&T编译器已经知道如何取消引用。通过返回引用而不是值,您可以避免复制/移动(这可能并不总是可能!)并允许&*x (or &x当它被强制时)参考actual char that DerefExample保存而不是临时副本。

也可以看看:

  • 为什么 Deref::deref 本身的返回类型是引用? https://stackoverflow.com/q/31624743/155423
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么对 Deref::deref 结果断言会因类型不匹配而失败? 的相关文章

随机推荐