String 为什么是字符串文本&;str代替生锈的绳子?

String 为什么是字符串文本&;str代替生锈的绳子?,string,rust,heap-memory,string-literals,stack-memory,String,Rust,Heap Memory,String Literals,Stack Memory,我只是想问为什么Rust决定对字符串文本使用&str,而不是string。Rust是否可以自动将字符串文字转换为字符串,并将其放在堆上,而不是放在堆栈中?要创建字符串,您必须: 在堆上保留一个位置(分配),然后 将所需内容从只读位置复制到新分配的区域 如果像“foo”这样的字符串文字同时执行这两个操作,那么每个字符串将被有效地分配两次:一次作为只读字符串在可执行文件中,另一次作为堆中。您不能仅仅引用存储在可执行文件中的原始只读数据 &str文本使您能够访问最有效的字符串数据:启动时出现在可执

我只是想问为什么Rust决定对字符串文本使用
&str
,而不是
string
。Rust是否可以自动将字符串文字转换为
字符串
,并将其放在堆上,而不是放在堆栈中?

要创建
字符串
,您必须:

  • 在堆上保留一个位置(分配),然后
  • 将所需内容从只读位置复制到新分配的区域

如果像
“foo”
这样的字符串文字同时执行这两个操作,那么每个字符串将被有效地分配两次:一次作为只读字符串在可执行文件中,另一次作为堆中。您不能仅仅引用存储在可执行文件中的原始只读数据

&str
文本使您能够访问最有效的字符串数据:启动时出现在可执行映像中的字符串数据,由编译器连同组成程序的指令放在那里。它指向的数据不存储在堆栈上,堆栈分配的只是指针/大小对,就像任何锈片一样


“foo”
desugar转换成现在拼写为
“foo.”的to_owned()
将使其速度变慢,节省空间,并且可能需要另一种语法才能获得非分配
&str
。毕竟,您不希望
x==“foo”
分配一个字符串只是为了立即扔掉它。Python之类的语言通过使字符串不可变来缓解这一问题,这允许它们缓存源代码中提到的字符串。在锈蚀突变<代码>字符串< /代码>通常是创建它的整个点,因此策略不起作用。

< P>为了理解推理,请认为RID想要成为系统编程语言。一般来说,这意味着它需要(除其他外)(a)尽可能高效,(b)让程序员完全控制堆内存的分配和释放。Rust的一个用例是内存非常有限的嵌入式编程

因此,Rust不希望在没有严格必要的情况下分配堆内存。字符串文本在编译时已知,可以写入可执行文件/库的
ro.data
部分,因此它们不会占用堆栈或堆空间

现在,考虑到Rust不想在堆上分配值,它基本上被迫将字符串文本视为
&str
string
s拥有自己的值,可以移动和删除,但是如何删除
ro.data
中的值呢?你真的不能这么做,所以
&str
是最合适的


此外,将字符串文本视为
&str
(或者更准确地说,视为
&'static str
)具有所有优点,但没有任何缺点。它们可以在多个地方使用,可以共享而不必担心使用堆内存,而且永远不必删除。此外,它们可以随意转换为所拥有的
String
s,因此将它们作为
String
提供始终是可能的,但您只在需要时支付成本。

理论上,当然。但是它会慢一些,有什么好处呢?“把它放在堆上,而不是放在堆栈中”,我猜字符串文本会放在ro.data部分。Re:投票结束后,我不同意这个问题会导致基于意见的答案。这种设计有非常明确的原因。“你不能仅仅引用存储在可执行文件中的原始只读数据。”为什么不呢?我认为只要字符串不是mut,这是可能的。如果数据要变异,那么无论如何都必须复制。因此,似乎使用字符串的任何一种方法都应该可以不受惩罚地工作。我错过了什么?@BlackShift为什么不因为
String
保证引用堆分配的数据。您甚至可以将其转换为或不重新分配。我认为只要字符串不是mut,这是可能的没有非mut
字符串这样的东西-只要你拥有它,你就可以一直拥有它。谢谢@user4815162342。我不知道可以使不可变的变量变为可变的。我想这是有道理的,因为不变性/常量的一个重要原因是确保程序的不同部分不会损坏其他部分所依赖的数据。Rust已经解决了这个问题。
让mut s=s
,因此它确实有效地使原始字符串mut(而不是复制数据)。因此,如果非mut字符串可以引用只读数据,事情就会破裂,这是我没有预料到的,再次感谢。是的,我想这一定是发生了什么,所以我想证明它(并在这里为未来的读者分享证明)。为什么不能删除
ro.data
中的值是一个问题?锈可以假装掉下来继续,还是会引起问题?(编辑:我真的很想知道为什么str会存在,而字符串文字似乎是答案的一个重要部分。)问题是字符串拥有数据,当数据本身被删除时,它会删除数据。可以检查它所拥有的数据是否在
ro.data
中(尽管跨平台也可能很困难),然后避免丢失,但这会使实现更加复杂。类型
String
str
Vec
[T]
中具有等效性。使用RITE的所有权和共享引用模型,您确实需要一些类似于<代码>和STR>代码>的东西,不仅仅是因为字符串文字。也可以认为, String 拥有并可以修改它的数据,而不是真正想用代码< > Ro.DATA < /代码>中的字符串文字/东西来做的事情。谢谢@保罗。我不知道即使是非mut字符串也必须假定其数据是可写的(因为它的所有者可以将其设置为mut)。和字符串文字必须是只读的,以提高性能