簡體   English   中英

Rust 遞歸引用另一個結構中的“self”

[英]Rust recursive reference to "self" in another struct

我有兩個實現不同方法(A 和 B)的 Rust 結構,當我實例化 B 時,我希望這個 B 將 A 作為結構成員。

在 Go 中,這可以通過以下方式輕松完成

type A struct {
  b *B
}

type B struct {
  a *A
}

我試過 Box 或 Rc/RefCell 但不知道。

這基本上是我需要的:

pub struct A<T: Tester> ...

pub struct B<T: Tester> {
  pub a: Box<A<T>>,
}

impl<T> A<T>
where
    T: Tester,
{
  pub fn run(&self) {
    let to_add = B {
      a: Box::new(self),
    }
  }

這個問題深入到所有權的話題中。

你總是要問自己:誰擁有什么?

在您的情況下,在run函數中, self是一個不可變的引用。 這意味着self對象由其他人擁有,而我們只是借用了它。

可悲的是,這意味着我們不能從中創建一個Box ,因為這需要我們擁有self (因為Box::new()取得了它所給對象的所有權)

所以我們能做的就是將借來的self對象傳遞給B對象。

可悲的是,現在有一個問題,這取決於您的用例。 每個借用的對象都與生命周期相關聯,以確保在原始對象被銷毀之前返回借用。 如果您創建一個包含對A的引用的B對象,則B對象將繼承該生命周期。 當然可以這樣做,但是手動生命周期管理是 Rust 中的一個高級主題,因為處理它可能會令人沮喪。

我建議您閱讀有關如何在 Rust 中管理生命周期的教程。

只是為了演示這看起來如何:

use std::marker::PhantomData;

pub trait Tester {}

pub struct A<T: Tester> {
    _x: PhantomData<T>,
}

pub struct B<'a, T: Tester> {
    pub a: &'a A<T>,
}

impl<T> A<T>
where
    T: Tester,
{
    pub fn run(&self) {
        let to_add = B { a: self };
    }
}

忽略PhantomData ,這只是使具有未使用泛型的結構編譯的虛擬對象。

to_add對象現在具有&self的生命周期,因此如果您嘗試將其存儲在外部某處或將其傳遞給線程或類似的東西,它會告訴您這會對其生命周期造成問題。 但當然,這一切都取決於您的用例。


type A struct {
  b *B
}

type B struct {
  a *A
}

在 Rust 中,這種構造幾乎是不可能的。 它被稱為自引用數據結構,不能由 Rusts 借用檢查器管理。 在其更簡單的形式中,您可以相互使用Arc / Rc ,這將造成內存泄漏(這在某種程度上可以通過Weak解決,但同樣,必須考慮到誰擁有它)。 在更復雜的形式中,您需要使用原始指針Pinunsafe

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM