“锈”中的<
<-算子不是稳定锈蚀的一部分。至少现在还不是。
有一个RFC,它建议使用<-语法直接将新对象写入内存中的特定位置,以替代另一个RFC,后者建议使用in。这是(当前不稳定的) box语法的概括,它允许直接分配给堆,而不需要临时堆栈分配。
目前,在不使用unsafe代码的情况下无法做到这一点,而且通常需要首先在堆栈上分配。对这个RFC中的潜在问题进行了讨论,这是相关RFCs链中的第一个问题,并给出了背景动机,但主要原因是:
使用需要将对象写入特定内存地址的硬件。您现在可以在Rust中不安全地这样做了,但是如果SDK能够为此提供一个安全的、可执行的API,那就更好了。直接写入堆中预先分配的部分比每次分配新内存要快。当为一个新对象分配内存时,直接在堆上这样做比先在堆栈上分配,然后克隆或移动要快一些。在C++中,有一个名为"placement“的特性,它通过允许您向new提供一个参数来实现这一点,该参数是一个用于开始写入的现有指针。例如:
代码语言:javascript运行复制// For comparison, a "normal new", allocating on the heap
string *foo = new string("foo");
// Allocate a buffer
char *buffer = new char[100];
// Allocate a new string starting at the beginning of the buffer
string *bar = new (buffer) string("bar");据我所知,上面的C++示例可能类似于使用<-的Rust中的
代码语言:javascript运行复制// Memory allocated on heap (with temporary stack allocation in the process)
let foo = Box::new(*b"foo");
// Or, without the stack allocation, when box syntax stabilises:
let foo = box *b"foo";
// Allocate a buffer
let mut buffer = box [0u8; 100];
// Allocate a new bytestring starting at the beginning of the buffer
let bar = buffer[0..3] <- b"bar";即使实现了布局功能,我也不会期望这样的代码按原样编译。但是请注意,在Rust中,目前无法执行最后一行试图做的事情:在缓冲区开始时直接分配b"bar",而不首先在堆栈上分配。在现在的铁锈里,没有办法做到这一点。即使是unsafe代码在这里也帮不了你。您仍然必须先在堆栈上分配,然后将其克隆到缓冲区中:
代码语言:javascript运行复制// Note that b"bar" is allocated first on the stack before being copied
// into the buffer
buffer[0..3].clone_from_slice(&b"bar"[0..3]);
let bar = &buffer[0..3];box语法在这里也没有帮助。这将分配新的堆内存,然后仍然必须将数据复制到缓冲区。
对于在堆上分配新对象时避免临时堆栈分配的更简单情况,box语法将在稳定时解决这个问题。铁锈需要在将来的某个时候解决更复杂的问题,但还不确定<-是否会出现。