前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Rust日报】2024-04-30 在 Rust 中设计一个带有 unsafe & union 的高效内存布局

【Rust日报】2024-04-30 在 Rust 中设计一个带有 unsafe & union 的高效内存布局

作者头像
MikeLoveRust
发布2024-05-10 16:41:32
1330
发布2024-05-10 16:41:32
举报

在 Rust 中设计一个带有 unsafe & union 的高效内存布局

这是关于如何构建 CLI 电子表格程序的系列博文中的第一篇博文,主要是因为我厌倦了所有其他电子表格的缺陷。在这篇博文中,我将设计电子表格单元格中每个值的内存布局,因此我们应该从以下问题开始:电子表格单元格包含什么?

  • A number? Perhaps!
  • A string of characters? Perhaps!
  • A formula, which is itself a domain-specific-language? Perhaps!

然而,这还不止于此。我不知道在 Excel 中是否是这种情况,但是在 Google Docs中,一个单元格可以被覆盖它的另一个单元格上显示的矩阵覆盖。矩阵和迭代器将是这个电子表格引擎的核心设计,但这是另一篇博文。不过,这意味着值要么是前面列出的值之一,要么是生成这些值的迭代器。

  • 第一次尝试:动态分发 (dynamic dispatch)
  • 通过枚举分发
  • 十进制数字类型,ft tagged pointers
  • 现在有了联合,也称为 C 的未标记枚举或 Friedrich Transmute。
  • 手动实现 iter dyn
  • TaggedPtr 的进一步讨论

使用 nolife 解决生命周期问题

该库允许构建包含引用的结构体,并使其与所引用的数据一起存活,而无需生命周期。

这对于零拷贝解析器来说尤其有用,因为零拷贝解析器会借用源数据构建复杂的(可能代价高昂的)表示法。

本库利用 async 函数实现了这一目标。这个库只是提供了一种方法,以可控的方式将引用放到 async 函数之外。

代码语言:javascript
复制
// Given the following types:
struct MyData(Vec<u8>);
struct MyParsedData<'a>(&'a mut MyData, /* ... */);

// 1. Define a helper type that will express where the lifetimes of the borrowed representation live.
struct MyParsedDataFamily; // empty type, no lifetime.
impl<'a> nolife::Family<'a> for MyParsedDataFamily {
    type Family = MyParsedData<'a>; // Indicates how the type is tied to the trait's lifetime.
    // you generally want to replace all lifetimes in the struct with the one of the trait.
}

// 2. Define a function that setups the data and its borrowed representation:
fn my_scope(
    data_source: Vec<u8>, // ? all parameters that allow to build a `MyData`
) -> impl nolife::TopScope<Family = MyParsedDataFamily> // ? use the helper type we declared
{
    nolife::scope!({
        let mut data = MyData(data_source);
        let mut parsed_data = MyParsedData(&mut data); // imagine that this step is costly...
        freeze_forever!(&mut parsed_data) // gives access to the parsed data to the outside.
                       /* ? reference to the borrowed data */
    })
}

// 3. Open a `BoxScope` using the previously written async function:
let mut scope = nolife::BoxScope::<MyParsedDataFamily>::new_dyn(my_scope(vec![0, 1, 2]));

// 4. Store the `BoxScope` anywhere you want
struct ContainsScope {
    scope: nolife::BoxScope<MyParsedDataFamily>,
    /* other data */
}

// 5. Lastly, enter the scope to retrieve access to the referenced value.
scope.enter(|parsed_data| { /* do what you need with the parsed data */ });

ReadMore: https://github.com/dureuill/nolife

From 日报小组 Koalr

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-05-01,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 Rust语言学习交流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在 Rust 中设计一个带有 unsafe & union 的高效内存布局
  • 使用 nolife 解决生命周期问题
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com