Mojo值的生命周期(Death of a value)详解

一旦不再使用某个值/对象,Mojo 就会将其销毁。Mojo 不会等到 代码块结束(甚至不会等到表达式结束)才销毁未使用的值。它使用在每个子表达式之后运行的“尽快”(ASAP)销毁策略来销毁值。即使在像这样的表达式中a+b+c+d,Mojo 也会在不再需要中间值时立即销毁它们。

Mojo 使用静态编译器分析来查找值最后一次使用的位置。然后,Mojo 立即结束该值的生命周期并调用析__del__() 构函数来执行该类型的任何必要清理。

例如,请注意__del__()每个实例的析构函数被调用的时间MyPet:

@value
struct MyPet:
    var name: String
    var age: Int

    fn __del__(owned self):
        print("Destruct", self.name)

fn pets():
    var a = MyPet("Loki", 4)
    var b = MyPet("Sylvie", 2)
    print(a.name)
    # a.__del__() runs here for "Loki"

    a = MyPet("Charlie", 8)
    # a.__del__() runs immediately because "Charlie" is never used

    print(b.name)
    # b.__del__() runs here

pets()

输出为:

Loki
Destruct Loki
Destruct Charlie
Sylvie
Destruct Sylvie

请注意,每个值的初始化都与对析构函数的调用相匹配,并且a实际上会被销毁多次 - 每次收到新值时都会销毁一次。

大多数结构不需要自定义析构函数,如果你没有定义析构函数,Mojo 会自动添加一个无操作析构函数。

默认销毁行为


您可能想知道 Mojo 如何在没有自定义析构函数的情况下销毁类型,或者为什么无操作析构函数很有用。如果类型只是字段的集合(如示例)MyPet,则 Mojo 只需销毁字段:MyPet不会动态分配内存或使用任何长期存在的资源(如文件句柄)。当值被销毁时,对于MyPet的销毁无需采取任何特殊操作。

查看各个字段,MyPet包括一个Int和String。

Mojo的Int称其为简单类型。它是静态大小位数。Mojo 确切知道它有多大,因此可以重复使用这些位来存储其他内容。

Mojo的String值稍微复杂一些。Mojo 字符串是可变的。该 String对象有一个内部缓冲区 - 一个 List字段,它保存组成字符串的字符。AList将其内容存储在堆上动态分配的内存中,因此字符串可以增大或缩小。字符串本身没有任何特殊的析构函数逻辑,但当 Mojo 销毁字符串时,它会调用该字段的析构函数 List,从而取消分配内存。

由于String和Int不需要任何自定义析构函数逻辑,它们都具有无操作析构函数:字面意思是__del__()不执行任何操作的方法。这似乎毫无意义,但这意味着 Mojo 可以在任何值的生命周期结束时调用其析构函数。这使得编写通用容器和算法变得更加容易。

ASAP 销毁的好处


与其他语言类似,Mojo 遵循对象/值在构造函数(init())中获取资源并在析构函数(del())中释放资源的原则。但是,Mojo 的 ASAP 销毁比基于范围的销毁具有一些优势(例如 C++ RAII 模式,它等到代码范围结束后才销毁值):

  • 最后一次使用时立即销毁值与“移动”优化完美结合,将“复制 + 删除”对转换为“移动”操作。
  • 在 C++ 中,在作用域末尾销毁值对于某些常见模式(如尾部递归)而言是有问题的,因为析构函数调用发生在尾部调用之后。对于某些函数式编程模式而言,这可能是一个严重的性能和内存问题,但在 Mojo 中则不是问题,因为析构函数调用始终发生在尾部调用之前。

此外,Mojo 的 ASAP 销毁在 Python 风格的def 函数中效果很好。这是因为 Python 实际上不提供超出函数范围的范围,因此 Python 垃圾收集器清理资源的频率比基于范围的销毁策略更高。但是,Mojo 不使用垃圾收集器,因此 ASAP 销毁策略提供的销毁保证比 Python 更细粒度。

Mojo 的销毁策略与 Rust 和 Swift 的工作方式更相似,因为它们都具有强大的值所有权跟踪功能并提供内存安全性。一个区别是 Rust 和 Swift 需要使用动态“删除标志” ——它们维护隐藏的影子变量来跟踪值的状态以提供安全性。这些通常会被优化掉,但 Mojo 方法完全消除了这种开销,

  • 27
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

启航学途

您的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值