在内部结构上实现的 Deref 特性中 &self 指的是什么?
What does &self refer to in the Deref trait implemented on the Inner struct?
我在 reddit post 上找到了这段代码,这让我很困惑。
//We'll recurse all we want, thank you very much!
#![allow(unconditional_recursion)]
use std::ops::Deref;
#[derive(Debug)]
struct Outer<T: Deref<Target = Outer<T>>> {
inner: T,
}
impl<T: Deref<Target = Outer<T>>> Deref for Outer<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Debug)]
struct Inner {}
impl Deref for Inner {
type Target = Outer<Inner>;
fn deref(&self) -> &Self::Target {
//Look at which struct we're implementing Deref for,
//and then read the next line very carefully.
&self.inner
}
}
const I: Inner = Inner {};
const O: Outer<Inner> = Outer { inner: I };
fn main() {
println!("{:?}", O.inner);
//Could just keep adding asterisks forever!
println!("{:?}", *O.inner);
println!("{:?}", **O.inner);
println!("{:?}", ***O.inner);
println!("{:?}", O);
//Could just keep adding asterisks forever!
println!("{:?}", *O);
println!("{:?}", **O);
println!("{:?}", ***O);
}
具体在这里:
impl Deref for Inner {
type Target = Outer<Inner>;
fn deref(&self) -> &Self::Target {
//Look at which struct we're implementing Deref for,
//and then read the next line very carefully.
&self.inner
}
}
函数return如何引用属于另一个结构的字段? &self 在这里实际上指的是 Outer 吗?
(此代码每次都因堆栈溢出而崩溃)
确实 Inner
上没有 inner
。但在放弃之前,编译器会想,“等等,Inner
是否有一些 Deref
实现?”答案当然是有!我们正在写它!那么,它 return 是什么意思? Outer<Inner>
?好吧,尝试取消引用并在 Outer<Inner>
上找到 inner
!也就是说,&self.inner
被转换为 &<Self as Deref>::deref(&self).inner
。那就是 在行动。
当然,因为我们 已经 在 <Inner as Deref>::deref()
中,我们再次调用它,递归地......一次又一次......直到我们炸毁堆栈。如果您要删除顶部的 #[allow(unconditional_recursion)]
,编译器会警告您 (playground):
warning: function cannot return without recursing
--> src/main.rs:22:5
|
22 | fn deref(&self) -> &Self::Target {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
...
25 | &self.inner
| ---------- recursive call site
|
= note: `#[warn(unconditional_recursion)]` on by default
= help: a `loop` may express intention better if this is on purpose
但是当你说 #[allow(unconditional_recursion)]
时,你告诉编译器“相信我,我知道我在做什么”所以它只是耸耸肩并继续。
我在 reddit post 上找到了这段代码,这让我很困惑。
//We'll recurse all we want, thank you very much!
#![allow(unconditional_recursion)]
use std::ops::Deref;
#[derive(Debug)]
struct Outer<T: Deref<Target = Outer<T>>> {
inner: T,
}
impl<T: Deref<Target = Outer<T>>> Deref for Outer<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
#[derive(Debug)]
struct Inner {}
impl Deref for Inner {
type Target = Outer<Inner>;
fn deref(&self) -> &Self::Target {
//Look at which struct we're implementing Deref for,
//and then read the next line very carefully.
&self.inner
}
}
const I: Inner = Inner {};
const O: Outer<Inner> = Outer { inner: I };
fn main() {
println!("{:?}", O.inner);
//Could just keep adding asterisks forever!
println!("{:?}", *O.inner);
println!("{:?}", **O.inner);
println!("{:?}", ***O.inner);
println!("{:?}", O);
//Could just keep adding asterisks forever!
println!("{:?}", *O);
println!("{:?}", **O);
println!("{:?}", ***O);
}
具体在这里:
impl Deref for Inner {
type Target = Outer<Inner>;
fn deref(&self) -> &Self::Target {
//Look at which struct we're implementing Deref for,
//and then read the next line very carefully.
&self.inner
}
}
函数return如何引用属于另一个结构的字段? &self 在这里实际上指的是 Outer 吗?
(此代码每次都因堆栈溢出而崩溃)
确实 Inner
上没有 inner
。但在放弃之前,编译器会想,“等等,Inner
是否有一些 Deref
实现?”答案当然是有!我们正在写它!那么,它 return 是什么意思? Outer<Inner>
?好吧,尝试取消引用并在 Outer<Inner>
上找到 inner
!也就是说,&self.inner
被转换为 &<Self as Deref>::deref(&self).inner
。那就是
当然,因为我们 已经 在 <Inner as Deref>::deref()
中,我们再次调用它,递归地......一次又一次......直到我们炸毁堆栈。如果您要删除顶部的 #[allow(unconditional_recursion)]
,编译器会警告您 (playground):
warning: function cannot return without recursing
--> src/main.rs:22:5
|
22 | fn deref(&self) -> &Self::Target {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
...
25 | &self.inner
| ---------- recursive call site
|
= note: `#[warn(unconditional_recursion)]` on by default
= help: a `loop` may express intention better if this is on purpose
但是当你说 #[allow(unconditional_recursion)]
时,你告诉编译器“相信我,我知道我在做什么”所以它只是耸耸肩并继续。