簡體   English   中英

如何在 Rust 中創建自引用 AST?

[英]How to create self-referential AST in Rust?

假設我們有一個非常簡單的編程語言 AST,只有函數和調用

use std::sync::Arc;

struct Function {
    pub body: Vec<Call>
}

struct Call {
    pub function: Arc<Function> 
}

現在我們要遞歸調用函數:

let f = Arc::new(Function { body: vec![Call {function: f.clone()}] }) 
// Doesn't work, as we haven't created Arc yet
let mut f = Arc::new(Function { body: vec![] });
f.body.push(Call { function: f.clone() })
// Doesn't work, because Arc has immutable data

這個問題可以在Call中使用Arc<Mutex<_>>Arc<RwLock<_>>來解決:

use std::sync::{Arc, RwLock}

struct Call {
    pub function: Arc<RwLock<Function>> 
}

然后創建:

let f = Arc::new(RwLock::new(Function { body: vec![] }));
f.write().unwrap().body.push(Call { function: f.clone() })

但是現在您需要始終在任何地方編寫f.write().unwrap()f.read().unwrap() ,即使 function僅在構造時可變。

你能做比這更好的事嗎?

對父指針使用Weak k。 無論如何,您都需要這樣做才能進行適當的銷毀。 然后使用Arc::new_cyclic()

use std::sync::{Arc, Weak};

struct Function {
    pub body: Vec<Call>,
}

struct Call {
    pub function: Weak<Function>,
}

let f = Arc::new_cyclic(|f| Function {
    body: vec![Call {
        function: Weak::clone(f),
    }],
});

暫無
暫無

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

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