【问题标题】:Is there any mechanism to generate an "ownership tree" visualization with Rust or the Rust tooling?是否有任何机制可以使用 Rust 或 Rust 工具生成“所有权树”可视化?
【发布时间】:2019-12-20 14:10:05
【问题描述】:

"Programming Rust" by Jim Blandy & Jason Orendorff 的第 4 章中说,

由此可见,所有者和他们拥有的价值形成了树:您的所有者是您的父母,而您拥有的价值是您的孩子。每棵树的最终根是一个变量;当该变量超出范围时,整个树都会随之消失。 我们可以在作曲家的图表中看到这样的所有权树:它不是搜索树数据结构意义上的“树”,也不是由 DOM 元素组成的 HTML 文档。相反,我们有一个由混合类型构建的树,Rust 的单一所有者规则禁止任何可能使排列比树更复杂的结构重新连接。 Rust 程序中的每个值都是某个树的成员,根植于某个变量。

提供了一个例子,

这很简单而且很漂亮,但是有没有任何机制可以使用 Rust 或 Rust 工具生成“所有权树”可视化?调试时可以转储所有权树吗?

【问题讨论】:

  • 不,没有。

标签: rust ownership


【解决方案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 可能会开始遍历这些引用。调试它们不属于它们并不重要。事实上,State::Ugly 内部的&amp;'static str 就是这种情况。构成字符串的实际字节不属于任何变量,它们是硬编码的并且存在于程序本身中。只要程序运行,它们就会存在。

【讨论】:

    猜你喜欢
    • 2010-12-21
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 2016-08-10
    相关资源
    最近更新 更多