以下是Rust编程语言中的Deref示例,除了我添加了另一个断言.
为什么assert_eq和deref平等'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当它裹挟)来指代实际 char是DerefExample持有,而不是一个临时副本.
也可以看看: