使用某些编程语言时,您可能会面临的挑战是必须手动分配和释放内存。当程序的多个部分需要访问同一内存时,很难跟踪谁“拥有”某个值并确定何时是释放它的正确时间。如果您犯了一个错误,可能会导致“释放后使用”错误、“双重释放”错误或“内存泄漏”错误,其中任何一个都可能是灾难性的。
Mojo 可确保每次只有一个变量拥有每个值,从而避免这些错误,同时仍允许您与其他函数共享引用。当所有者的生命周期结束时,Mojo会销毁该值。
在本节,我们将解释管理此所有权模型的规则以及如何指定定义如何将值共享到函数中的不同参数约定。
在所有编程语言中,代码质量和性能在很大程度上取决于函数如何处理参数值。也就是说,函数接收的值是唯一值还是引用,以及它是可变的还是不可变的,会产生一系列影响,这些影响决定了语言的可读性、性能和安全性。
在 Mojo 中,我们希望默认提供完整的值语义,从而提供一致且可预测的行为。但作为系统编程语言,我们还需要提供对内存优化的完全控制,这通常需要引用语义。诀窍是引入引用语义,通过跟踪每个值的生命周期并在正确的时间(并且只一次)销毁每个值,从而确保所有代码都是内存安全的。所有这些都是通过使用参数约定在 Mojo 中实现的,这些约定确保每个值一次只有一个所有者。
参数约定指定参数是可变的还是不可变的,以及函数是否拥有该值。每个约定都由参数声明开头的关键字定义:
例如,此函数有一个可变引用参数和一个不可变引用参数:
fn add(inout x: Int, borrowed y: Int): x += y fn main(): var a = 1 var b = 2 add(a, b) print(a) print(b) 输出:
3 2 您可能已经看到过一些没有声明约定的函数参数。默认情况下,所有参数都是borrowed。但是def和fn 函数对待borrowed参数的方式略有不同:
var my_copy = borrowed_arg 函数中borrowed和之间的区别可能有点微妙:owneddef