【问题标题】:What is the <- symbol in Rust?Rust 中的 <- 符号是什么?
【发布时间】:2018-09-20 13:41:28
【问题描述】:

Rust 中的&lt;- 运算符/表达式是什么?你可以找到the symbol here

我碰巧在看一个描述 Rust 中的表达式和操作的页面。我不会用 Rust 编程,所以我问了一个支持 Rust 的朋友这个符号是什么,但他也不知道它是什么。

【问题讨论】:

  • 看起来placement_new 被废弃了...所以现在它什么都不做?
  • 使用这个会产生这个错误:error[E0658]: placement-in expression syntax is experimental and subject to change. (see issue #27779)。如果获得批准,看起来它将像这样使用:let v = Vec::new(); // The old syntax in v.back() { 10 }; // The new syntax. v.back() &lt;- 10; // This clearly looks better to me.
  • @turbulencetoo 请注意链接的位置。这是官方 RFC 存储库的一个分支,不是官方本身The official RFC repo 包含更新,例如该 RFC 未被接受。

标签: syntax rust operators placement-new


【解决方案1】:

&lt;- 运算符不是稳定版 Rust 的一部分。至少现在还没有。

有一个RFC 提出了涉及&lt;- 的语法,用于将新对象直接写入内存中的特定位置,作为another RFC 的替代方案,它提出了in。这是(目前不稳定的)box 语法的概括,它允许您直接分配给堆,而无需临时分配堆栈。

目前,如果不使用unsafe 代码,则无法做到这一点,而且通常您需要先在堆栈上进行分配。 this RFC 中讨论了潜在问题,这是相关 RFC 链中的第一个,并给出了背景动机,但关键原因是:

  • 使用期望将对象写入特定内存地址的硬件。您现在可以在 Rust 中不安全地执行此操作,但如果 SDK 可以为此提供安全且高性能的 API,那就更好了。
  • 直接写入堆的预分配部分比每次都分配新内存更快。
  • 为新对象分配内存时,直接在堆上执行此操作会更快,而不是先在堆栈上分配然后克隆或移动。

在 C++ 中,有一个名为“placement new”的功能,它通过让您向new 提供一个参数来实现这一点,这是一个开始写入的现有指针。例如:

// 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++ 示例在带有 &lt;- 的 Rust 中可能看起来像这样:

// 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",而不是先在堆栈上分配。现在在 Rust 中,没有办法做到这一点。即使unsafe 代码在这里也无济于事。您仍然必须先在堆栈上分配,然后将其克隆到缓冲区:

// 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 语法将在稳定时解决该问题。 Rust 将需要在未来某个时候解决更复杂的情况,但尚不确定&lt;- 是否会出现。

【讨论】:

  • 值得注意的是,由于各种健全性问题,这些 RFC 最初被接受(因此为什么它们在每晚半实现)but as of a week ago have been 'unaccepted'。很可能必须提交一个全新的 RFC 才能返回。 box 语法仍然存在,因为编译器本身大量使用它。
猜你喜欢
  • 2015-11-01
  • 1970-01-01
  • 2019-06-21
  • 2017-03-24
  • 2014-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
相关资源
最近更新 更多