Rust 和Erlang的对比(3)

Erlang: 变量只绑定在函数的范围内,并由特定于当前进程的垃圾收集器释放。因此, 每个变量的生命周期与使用它的函数相同。也就是说,程序应该尽可能地模块化到函数中, 以便有效地使用内存。此外, 您甚至可以使用特殊的触发器来触发垃圾回收,在需要时调用Erlang: gc ()触发垃圾回收. 

Rust: Rust没有垃圾回收Rust 使用生命周期来管理内存。一个范围内的每个变量(用花括号或函数的主体进行分隔)都被赋予一个新的生命周期,如果它不是从父进程中借出或引用的话。变量的生命周期不会在该变量被借用的范围结束时结束,它只在父范围的末尾结束。因此,每个变量的生命周期要么由当前范围管理,要么由父作用域管理,由编译器来确保这一点。在编译过程中,Rust暗自注入代码,以便当该变量的生命周期结束时,除去与变量相关的���。这种方法可以避免使用垃圾收集来确定哪些变量可以被释放。通过在函数内管理生命周期,Rust提供了对内存的细粒度控制。与Erlang函数在功能结束时触发垃圾收集的功能不同,在Rust中,您可以使用{}将您的代码划分为多个范围,而编译器将在每个作用域的末尾放置drop代码。 

变量绑定、所有权和借出

Erlang: Erlang有一个简单的绑定方式。如果一个变量之前是未绑定的,那么任何一个变量的出现都会被绑定到右边的值,否则它就是模式匹配的。Erlang中的任何类型都可以绑定到一个变量。变量只绑定在它们出现的函数上下文中,并且在不再使用时由特定于当前进程的垃圾收集器释放。数据的所有权不能转移给不同的变量。如果同一个函数上下文中的另一个变量想要拥有相同的数据,那么它必须克隆这个数据。这符合Erlang的不共享任何东西的理念,并使使用克隆值安全地发送到不同的节点或进程而不进行数据竞争。在 Erlang 中, 没有引用, 因此也没有借用。所有数据都被分配到堆上。 

Rust所有权和借出是Rust中两个强大的概念,使该语言在主流语言中独树一帜。这也正是为什么Rust被认为是低层次无数据竞争语言的非常重要的原因,这可以在不需要垃圾收集器的情况下提供内存安全,从而保证了最小的运行时开销。数据的所有权属于一个变量,这意味着没有其他变量可以共享该数据的所有权。如果需要的话,所有权被转移到一个不同的变量赋值上,旧变量不再有效。如果将变量作为参数发送给函数,则所有权也会被转移。这种操作称为move,因为数据的所有权被转移了。所有权有助于有效地管理内存。 

所有权规则:每个值在某一时刻会有一个明确的所有者:如果所有者超出范围,则该值会被垃圾收集。

当一个值的所有权被临时从拥有它的变量中借用到一个函数或一个变量时,就会发生借出了,要么是可变的,要么是不可变的。一旦借用超出了功能或{}分隔块的范围,所有权就会返回。在借用期间,父函数/范围对变量没有所有权,直到被借用的函数/范围结束为止。 

借出规则:对于一个变量,可以有任意数量的不可变引用,但是在一个范围内只能有一个不可变的引用。此外,可变和不可变引用不能在一个范围内共存。

引用计数

引用计数用于跟踪其他进程/线程对变量的使用。一个新进程/线程持有该变量时引用计数将增加,当一个进程/线程退出时引用计数将递减。当计数达到0时,值被删除。

Erlang: 当数据在Erlang中跨多个进程传递时,数据通过一条消息传递。这意味着它是被复制到其他进程的堆中的,而不是引用计数。在一个进程内复制的数据由每进程(per-process)垃圾回收器在其生命周期末尾进行垃圾回收。然而,超过64KB大小的binary跨Erlang进程传递时会被引用计数。 

Rust: 当数据在线程间共享时,数据不会被复制以提高效率。而是由一个引用计数器包装。引用有些特殊,因为多个可变引用可以传递给多个线程,但同时要对数据同步进行互斥。不可变数据的引用不需要互斥。 所有相关的检查都是在编译时完成的,并有助于防止Rust中的数据竞争。

消息传递

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/97c0db980c0ffb0e8e85ab46f9cbb20f.html