为什么断言 Deref::deref 的结果会因类型不匹配而失败?
Why does asserting on the result of Deref::deref fail with a type mismatch?
以下是 Deref
example from The Rust Programming Language 除了我添加了另一个断言。
为什么 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");
}
如果我取消注释该行,我会得到这个错误:
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
,因此我们有:
impl Deref for DerefExample<char> {
type Target = char;
fn deref(&self) -> &char {
&self.value
}
}
值得注意的是,deref
的 return 类型是对 char
的 引用 。因此,当您仅使用 x.deref()
时,结果是 &char
而不是 char
也就不足为奇了。请记住,此时 deref
只是另一种普通方法——它只是作为某些语言提供的特殊语法的 part 隐式调用。例如,*x
将调用 deref
并在适用时取消引用结果。 x.char_method()
和 fn_taking_char(&x)
也会多次调用 deref
然后对结果做进一步的处理。
为什么 deref
return 引用开头,你问?不是圆形的吗?好吧,不,它不是循环的:它减少了 库定义的智能指针指向编译器已经知道如何解引用的内置类型&T
。通过 returning 引用而不是值,您可以避免 copy/move(这可能并不总是可能的!)并允许 &*x
(或 &x
,当它被强制时)参考 DerefExample
持有的 actual char
而不是临时副本。
另请参阅:
以下是 Deref
example from The Rust Programming Language 除了我添加了另一个断言。
为什么 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");
}
如果我取消注释该行,我会得到这个错误:
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
,因此我们有:
impl Deref for DerefExample<char> {
type Target = char;
fn deref(&self) -> &char {
&self.value
}
}
值得注意的是,deref
的 return 类型是对 char
的 引用 。因此,当您仅使用 x.deref()
时,结果是 &char
而不是 char
也就不足为奇了。请记住,此时 deref
只是另一种普通方法——它只是作为某些语言提供的特殊语法的 part 隐式调用。例如,*x
将调用 deref
并在适用时取消引用结果。 x.char_method()
和 fn_taking_char(&x)
也会多次调用 deref
然后对结果做进一步的处理。
为什么 deref
return 引用开头,你问?不是圆形的吗?好吧,不,它不是循环的:它减少了 库定义的智能指针指向编译器已经知道如何解引用的内置类型&T
。通过 returning 引用而不是值,您可以避免 copy/move(这可能并不总是可能的!)并允许 &*x
(或 &x
,当它被强制时)参考 DerefExample
持有的 actual char
而不是临时副本。
另请参阅: