为什么这种相互参考结构在Rust中起着特定的生命作用?

发布于 2025-02-02 19:37:19 字数 2457 浏览 4 评论 0 原文

为什么以下代码编译?

我希望生锈的编译器告诉我

设置参考(store.barber.set(some(& barber)))时,“借用的价值不够长”。

因为理发师的寿命比shop较短。

use core::cell::Cell;

struct Shop<'a> {
    barber: Cell<Option<&'a Barber<'a>>>,
}

struct Barber<'a> {
    shop: Cell<Option<&'a Shop<'a>>>,
}

fn main() {
    let shop = Shop { barber: Cell::new(None) };
    {
        let barber = Barber { shop: Cell::new(Some(&shop))};
        shop.barber.set(Some(&barber));
    }
}

“ 在这里)。

注释/a3taps/newbie_how_can_i_reference_two_struct_in_each/“ rel =” nofollow noreferrer“>在这里。 但是,为什么整个事情都起作用,或者我的误解在哪里仍然不清楚。

进行编辑/启蒙

我在@netwaves答案上对代码

。如果链接不再起作用,也可以澄清这个问题。

内部范围只是为了使生活更加清晰。

用法看起来更像是这样:

use core::cell::Cell;

struct Shop<'a> {
    barber: Cell<Option<&'a Barber<'a>>>,
    shop_state: Cell<bool>,
}

impl<'a> Shop<'a> {
    fn change_barber_state(&self) {
        self.barber.get().unwrap().change_state();
    }

    fn change_state(&self) {
        self.shop_state.set(!self.shop_state.get());
    }
}

struct Barber<'a> {
    shop: Cell<Option<&'a Shop<'a>>>,
    barber_state: Cell<bool>,
}

impl<'a> Barber<'a> {
    fn change_state(&self) {
        self.barber_state.set(!self.barber_state.get());
    }

    fn change_shop_state(&self) {
        self.shop.get().unwrap().change_state();
    }
}

fn main() {
    let shop = Shop {
        barber: Cell::new(None),
        shop_state: Cell::new(false),
    };

    let barber = Barber {
        shop: Cell::new(Some(&shop)),
        barber_state: Cell::new(false),
    };
    shop.barber.set(Some(&barber));

    println!("{:?}", barber.barber_state);
    println!("{:?}", shop.shop_state);

    shop.change_barber_state();
    barber.change_shop_state();

    println!("{:?}", barber.barber_state);
    println!("{:?}", shop.shop_state);
}

通过同一范围,寿命是一样的吗?

我认为一生也是通过释放资源来给出的,这些资源以相反的顺序与声明发生。或仅当 drop 特质是特征是实施的?

Why does the following code compiles?

I would expect the Rust compiler to tell me

"borrowed value does not live long enough" when setting the reference (store.barber.set(Some(&barber));

Since barber has a shorter lifetime than shop.

use core::cell::Cell;

struct Shop<'a> {
    barber: Cell<Option<&'a Barber<'a>>>,
}

struct Barber<'a> {
    shop: Cell<Option<&'a Shop<'a>>>,
}

fn main() {
    let shop = Shop { barber: Cell::new(None) };
    {
        let barber = Barber { shop: Cell::new(Some(&shop))};
        shop.barber.set(Some(&barber));
    }
}

Playground

My assumption is confirmed by @jmb with his answer (here).

The code example comes from here.
But why the whole thing works or where my misunderstanding lies is still unclear to me.

Edit/Enlightenment

The code which I commented to on @Netwaves answer.

In case the link don't work anymore and also to clarify the question.

The inner scope was just to make the lifetime more clear.

A usage would look more like this:

use core::cell::Cell;

struct Shop<'a> {
    barber: Cell<Option<&'a Barber<'a>>>,
    shop_state: Cell<bool>,
}

impl<'a> Shop<'a> {
    fn change_barber_state(&self) {
        self.barber.get().unwrap().change_state();
    }

    fn change_state(&self) {
        self.shop_state.set(!self.shop_state.get());
    }
}

struct Barber<'a> {
    shop: Cell<Option<&'a Shop<'a>>>,
    barber_state: Cell<bool>,
}

impl<'a> Barber<'a> {
    fn change_state(&self) {
        self.barber_state.set(!self.barber_state.get());
    }

    fn change_shop_state(&self) {
        self.shop.get().unwrap().change_state();
    }
}

fn main() {
    let shop = Shop {
        barber: Cell::new(None),
        shop_state: Cell::new(false),
    };

    let barber = Barber {
        shop: Cell::new(Some(&shop)),
        barber_state: Cell::new(false),
    };
    shop.barber.set(Some(&barber));

    println!("{:?}", barber.barber_state);
    println!("{:?}", shop.shop_state);

    shop.change_barber_state();
    barber.change_shop_state();

    println!("{:?}", barber.barber_state);
    println!("{:?}", shop.shop_state);
}

Is the lifetime the same through the same scope?

I thought the lifetime is also given by freeing the resources, which happens in reverse order to the declaration. Or is this only relevant if the drop trait is implemented?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

可是我不能没有你 2025-02-09 19:37:19

为什么这种相互参考结构在Rust中起作用,并指定寿命?

简短答案:

确实如此,因为根据您的代码,它实际上寿命足够长。

说明

问题(没问题)是您在内部范围之后不再使用 shop ,因此编译器足够聪明,可以说您的程序没有错。
但是,如果您添加访问权限,他将开始抱怨,并且有充分的理由:

fn main() {
    let shop = Shop { barber: Cell::new(None) };
    {
        let barber = Barber { shop: Cell::new(Some(&shop))};
        shop.barber.set(Some(&barber));
    }
    shop.barber.get();
}

无法编译:

error[E0597]: `barber` does not live long enough
  --> src/main.rs:15:30
   |
15 |         shop.barber.set(Some(&barber));
   |                              ^^^^^^^ borrowed value does not live long enough
16 |     }
   |     - `barber` dropped here while still borrowed
17 |     shop.barber.get();
   |     ----------------- borrow later used here

Playground> Playground

问题扩展:

fn main() {
    let shop = Shop {
        barber: Cell::new(None),
        shop_state: Cell::new(false),
    };

    let barber = Barber {
        shop: Cell::new(Some(&shop)),
        barber_state: Cell::new(false),
    };
    shop.barber.set(Some(&barber));

    println!("{:?}", barber.barber_state);
    println!("{:?}", shop.shop_state);

    shop.change_barber_state();
    barber.change_shop_state();

    println!("{:?}", barber.barber_state);
    println!("{:?}", shop.shop_state);
}

您为什么认为这不应该编译?

显然, shop barber 在同一程度上,直到完成后。在这种情况下,免费顺序无关紧要,因为编译器已经知道它们都不会再使用,因此上述代码是完全安全的。

Why does this mutual referencing structures work in Rust with specified lifetimes?

Short answer:

It does because as per your code it actually lives long enough.

Explanation

The problem (no problem) is that you are not using shop anymore after the inner scope, so the compiler is smart enough to say nothing is wrong with your program.
But if you add an access he will start complaining, and with a good reason:

fn main() {
    let shop = Shop { barber: Cell::new(None) };
    {
        let barber = Barber { shop: Cell::new(Some(&shop))};
        shop.barber.set(Some(&barber));
    }
    shop.barber.get();
}

fails to compile with:

error[E0597]: `barber` does not live long enough
  --> src/main.rs:15:30
   |
15 |         shop.barber.set(Some(&barber));
   |                              ^^^^^^^ borrowed value does not live long enough
16 |     }
   |     - `barber` dropped here while still borrowed
17 |     shop.barber.get();
   |     ----------------- borrow later used here

Playground

On the question extension:

fn main() {
    let shop = Shop {
        barber: Cell::new(None),
        shop_state: Cell::new(false),
    };

    let barber = Barber {
        shop: Cell::new(Some(&shop)),
        barber_state: Cell::new(false),
    };
    shop.barber.set(Some(&barber));

    println!("{:?}", barber.barber_state);
    println!("{:?}", shop.shop_state);

    shop.change_barber_state();
    barber.change_shop_state();

    println!("{:?}", barber.barber_state);
    println!("{:?}", shop.shop_state);
}

Why do you think this should not compile?

Clearly both shop and barber life for the same extent, up to when main is finished. It doesn't matter the order of free in this case, since the compiler already know that none of them will be used anymore, so the above code is completely safe.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文