为什么 Nil 会增加一个枚举大小而不增加另一个枚举大小? Rust 枚举的内存是如何分配的?

2024-05-19

如果我定义以下枚举,Nil 不会增加枚举的大小:

  use std::mem::size_of;

  enum Foo {
    Cons(~char)
  }

  enum Bar {
    Cons(~char),
    Nil
  }

  println!("{}", size_of::<Foo>());
  println!("{}", size_of::<Bar>());

  // -> 4
  // -> 4

另一方面:

  enum Foo {
    Cons(char)
  }

  enum Foo {
    Cons(char),
    Nil
  }

Yields:

  // -> 4
  // -> 8

当我定义枚举时会发生什么?如何为这些结构分配内存?


枚举的一种简单方法是为其最大变体的内容以及判别式分配足够的空间。这是一个标准标记联盟.

Rust 比这聪明一点。 (它可能会更聪明,但目前还不是。)它知道给定一个~T,该内存位置至少有一个值cannot是:零。所以在像你这样的情况下enum { Cons(~T), Nil },它能够将其优化为一个字,并且内存中的任何非零值都有意义Cons(~T)以及内存意义中的零值Nil.

当你处理char,优化无法发生:零是有效的代码点。当它发生的时候,char被定义为 Unicode 代码点,所以它would实际上可以将变体优化到该空间中,最后有大量的备用位(Unicode 字符只需要 21 位,因此在 32 位空间中我们有 11 个备用位)。这证明了 Rust 的枚举判别式优化目前还不是特别聪明。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Nil 会增加一个枚举大小而不增加另一个枚举大小? Rust 枚举的内存是如何分配的? 的相关文章

  • 为什么我在子模块中需要“use”语句,但在 main.rs 中不需要?

    我不明白mod or use 我想mod将文件导入到项目中并use会使用它们 我有一个具有以下层次结构的项目 Cargo lock Cargo toml src display rs list rs main rs parser rs so
  • 堆内存问题

    有一个 WCF 自托管服务必须在 99 的时间内正常工作 有时我们会遇到这样的记忆问题 但问题发生后 服务一切正常 我们该如何处理这个问题 任何关于提供能够在不同情况下生存的强大服务的提示和要点都非常受欢迎 我不太确定问题出在哪里 但内存泄
  • SQL 中的链表

    在 MySQL 数据库中存储链接列表的最佳方法是什么 这样插入就很简单 即 您不必每次都重新索引一堆内容 并且可以轻松地按顺序拉出列表 使用 Adrian 的解决方案 但不是增加 1 而是增加 10 甚至 100 然后可以按照要插入的内容之
  • 需要澄清 NSAutoreleasePool

    每当我们打电话时autorelease方法 它的对象将是NSAutoreleasePool 当池耗尽时 它会向池中的所有对象发送释放消息 我的问题是 main函数中有一个NSAutoreleasePool 我想知道 当我们调用autorel
  • 某些数据结构是否比其他数据结构更适合函数式编程?

    In 现实世界哈斯克尔 http book realworldhaskell org 有一个标题为 没有数组或哈希表的生活 的部分 其中作者建议在函数式编程中首选列表和树 而在命令式程序中可能会使用数组或哈希表 这是有道理的 因为在创建新列
  • Xcode Instruments:模拟器中运行的 iPhone 应用程序的峰值 RAM?

    活动监视器 又名内存监视器 是 Xcode Instruments 中唯一可以测量在模拟器中运行的 iPhone 应用程序的总应用程序 RAM 使用情况的工具吗 只是显示瞬时有线 RAM 的那条线 与 iPhone 硬件相比 尤其是 OSX
  • 是否有在相似结构之间移动字段的语法?

    我有一个大结构Foo
  • 我需要释放手势识别器吗?

    如果我将手势识别器添加到名为的表格单元格中cell e g UILongPressGestureRecognizer longPressRecognizer UILongPressGestureRecognizer alloc initWi
  • 为什么不能收集一定范围的字符?

    我正在尝试生成一个包含小写 ASCII 字符的向量 这种更复杂的方法有效 let ascii lowercase b a b z map b b as char collect
  • 将异步函数包装在结构中时的生命周期

    我正在尝试将异步函数包装在结构中 例如 use std future Future struct X struct Y async fn f x X gt Y Y struct MyStruct
  • Rust 编译器不会将结构视为 Sized

    我试图将一个特质定义如下 pub struct Parameter
  • 如何“切换”枚举变体?

    我想编写一个函数 将提供的值切换 切换到枚举中的下一个值并在末尾环绕 enum Direction NORTH SOUTH EAST WEST 例如 NORTH gt SOUTH SOUTH gt EAST EAST gt WEST WES
  • 删除数组时出现访问冲突异常

    删除分配的内存时 出现 访问冲突读取位置 异常 如下所示 我有一个针对 Visual Studio 2010 工具集 v100 C 编译器编译的本机 dll 我有一个针对它的托管 dll 包装器 它是针对工具集 v90 编译的 因为我想以
  • C++:二叉树所有节点值的总和

    我正在准备面试 我被一个二叉树问题困住了 我们如何计算二叉树所有节点中存在的值的总和 优雅的递归解决方案 伪代码 def sum node if node NULL return 0 return node gt value sum nod
  • 如何根据键名称反序列化为枚举变体?

    我有两种形式的 JSON Example field 42 A 76 Example field 42 B 110 我想将它反序列化成这样的结构 struct Example field i32 an enum AnEnum where e
  • 对结构方法中的借用错误感到困惑

    我正在尝试为游戏中的实体系统编写一些代码 但出现此错误 因此我将代码浓缩为执行相同操作的代码 在实际代码中出现相同的错误 我不明白为什么编译器告诉我对self my list当函数超出范围时baz完成 我的 Rust 版本是rustc 1
  • 如何将 Box 转换为 &T?

    如果我有一个特征对象 我该如何调用一个需要特征对象的函数Box
  • 需要 gem 是否会加载所有内容,包括我不使用的东西?

    Assume x是一颗宝石 包含两者Hello and Goodbye类 如果我写一个程序require x 但仅使用Hello班级 是个Goodbye类也加载了吗 您包含脚本或文件 而不是 gem With require x 你加载文件
  • 如何指定 AsRef 的生命周期?

    我正在尝试编写一个函数来连接两个可迭代对象 其项目可以转换为OsStr引用 并且在尝试指定引用的生命周期时遇到了巨大的困难 use std convert AsRef use std ffi OsStr use std marker Pha
  • 如何在不消耗值的情况下实现添加特征[重复]

    这个问题在这里已经有答案了 当实施Add特质 还有其他一些 比如Mul Sub等 对于一个简单的结构体 必须完全消耗该结构体值 因此它的后续使用是不可能的 同时 内置原语 u8 usize等 实施Add同时允许之后使用它add被称为 我该如

随机推荐