是否有一种机制可以使用Rust或Rust工具生成“所有权树”可视化呢?

4
在《Rust编程》一书的第4章中,Jim Blandy和Jason Orendorff写道:
“因此,所有者和它们所拥有的值形成树形结构:你的所有者是父节点,你所拥有的值是子节点。每棵树的最终根节点是一个变量;当该变量超出作用域时,整个树都会随之消失。我们可以在作曲家的图表中看到这样的所有权树:它不是“树”数据结构或由DOM元素组成的HTML文档。相反,我们有一棵由多种类型构建的树,Rust的单一所有者规则禁止任何重新连接结构的操作,否则将使排列比树更复杂。Rust程序中的每个值都是某个变量根节点下的成员。”
提供了一个例子:

Rust Ownership Tree

这段文本的意思是:这个问题涉及Rust编程语言中是否有机制可以生成“所有权树”可视化,或者使用Rust工具进行生成?我在调试时能否转储所有权树?

没有。 - Shepmaster
1个回答

1

实际上并没有针对此的特定工具,但您可以通过派生Debug特征来获得相似的效果。当您为结构体派生Debug特征时,它会给您提供所有拥有数据的递归表示,以基本类型(例如stru32等)终止,或者遇到自定义Debug实现。

例如,这个程序:

use rand;

#[derive(Debug)]
enum State {
    Good,
    Bad,
    Ugly(&'static str),
}

#[derive(Debug)]
struct ExampleStruct {
    x_factor: Option<f32>,
    children: Vec<ExampleStruct>,
    state: State,
}

impl ExampleStruct {
    fn random(max_depth: usize) -> Self {
        use rand::Rng;
        let mut rng = rand::thread_rng();

        let child_count = match max_depth {
            0 => 0,
            _ => rng.gen::<usize>() % max_depth,
        };

        let mut children = Vec::with_capacity(child_count);

        for _ in 0..child_count {
            children.push(ExampleStruct::random(max_depth - 1));
        }

        let state = if rng.gen() {
            State::Good
        } else if rng.gen() {
            State::Bad
        } else {
            State::Ugly("really ugly")
        };

        Self {
            x_factor: Some(rng.gen()),
            children,
            state,
        }
    }
}

fn main() {
    let foo = ExampleStruct::random(3);
    dbg!(foo);
}

打印出类似这样的东西:
[src/main.rs:51] foo = ExampleStruct {
    x_factor: Some(
        0.27388978,
    ),
    children: [
        ExampleStruct {
            x_factor: Some(
                0.5051847,
            ),
            children: [
                ExampleStruct {
                    x_factor: Some(
                        0.9675246,
                    ),
                    children: [],
                    state: Ugly(
                        "really ugly",
                    ),
                },
            ],
            state: Bad,
        },
        ExampleStruct {
            x_factor: Some(
                0.70672345,
            ),
            children: [],
            state: Ugly(
                "really ugly",
            ),
        },
    ],
    state: Bad,
}

请注意,并非所有数据都在同一行上:子项存储在堆上的其他位置。它们不存储在ExampleStruct中,而只是由其拥有。
如果存储对事物的引用,则可能会变得混乱,因为Debug可能开始遍历这些引用。对于Debug来说,它们不拥有并不重要。事实上,这就是State::Ugly中的&'static str的情况。组成字符串的实际字节不属于任何变量,它们被硬编码并驻留在程序本身内。它们将存在于程序运行的整个过程中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接