问题描述
以下是 Deref
示例> Rust编程语言 ,除了我添加了另一个断言.
The following is the Deref
example from The Rust Programming Language except I've added another assertion.
为什么assert_eq
与deref
也等于'a'
?手动调用deref
后,为什么需要*
?
Why does the assert_eq
with the deref
also equal 'a'
? Why do I need a *
once I've manually called 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");
}
如果我取消注释该行,则会出现此错误:
If I uncomment the line, I get this error:
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'
是char
,所以我们有:
First, let's spell out the generic types for your specific example: 'a'
is char
, so we have:
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
,然后对结果做进一步的处理.
Notably, the return type of deref
is a reference to a char
. Thus it shouldn't be surprising that, when you use just x.deref()
, the result is a &char
rather than a char
. Remember, at that point deref
is just another normal method — it's just implicitly invoked as part of some language-provided special syntax. *x
, for example, will call deref
and dereference the result, when applicable. x.char_method()
and fn_taking_char(&x)
will also call deref
some number of times and then do something further with the result.
为什么您要问deref
为什么要返回引用?那不是通函吗?好吧,不是,这不是循环的:它减少库定义的智能指针,该指针指向编译器已经知道如何取消引用的内置类型&T
.通过返回引用而不是值,可以避免复制/移动(这可能并不总是可能的!),并允许&*x
(或强制执行时为&x
)引用 actual char
拥有DerefExample
而不是临时副本.
Why does deref
return a reference to begin with, you ask? Isn't that circular? Well, no, it isn't circular: it reduces library-defined smart pointers to the built-in type &T
which the compiler already knows how to dereference. By returning a reference instead of a value, you avoid a copy/move (which may not always be possible!) and allow &*x
(or &x
when it's coerced) to refer to the actual char
that DerefExample
holds rather than a temporary copy.
另请参阅:
这篇关于为什么对Deref :: deref的结果进行断言会因类型不匹配而失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!