为什么字符串文字 &str 而不是 Rust 中的 String?
Why are string literals &str instead of String in Rust?
我只是问为什么 Rust 决定对字符串文字使用 &str
而不是 String
。 Rust 难道不能自动将字符串文字转换为 String
并将其放在堆上而不是将其放入堆栈吗?
要创建 String
,您必须:
- 在堆上保留一个位置(分配),并且
- 将所需内容从 read-only 位置复制到新分配的区域。
如果像 "foo"
这样的字符串文字同时执行这两种操作,则每个字符串将有效地分配两次:一次在可执行文件中作为 read-only 字符串,另一次在堆上。您不能只引用存储在可执行文件中的原始 read-only 数据。
&str
文字使您可以访问最有效的字符串数据:启动时出现在可执行映像中的数据,由编译器与构成程序的指令一起放置在那里。它指向的数据未存储 在堆栈上 ,stack-allocated 只是 pointer/size 对,就像任何 Rust 切片一样。
将 "foo"
desugar 变成现在拼写的 "foo".to_owned()
会使它变得更慢和更少 space-efficient,并且可能需要 另一个 语法获得 non-allocating &str
。毕竟,您不希望 x == "foo"
分配一个字符串只是为了立即将其丢弃。像 Python 这样的语言通过使它们的字符串不可变来缓解这种情况,这允许它们缓存源代码中提到的字符串。在 Rust 中,变异 String
通常是创建它的全部要点,因此该策略行不通。
要理解其中的原因,请考虑 Rust 想要成为一种系统编程语言。一般来说,这意味着它需要(除其他外)(a)尽可能高效和(b)让程序员完全控制堆内存的分配和释放。 Rust 的一个用例是用于内存非常有限的嵌入式编程。
因此,Rust 不想在并非绝对必要的地方分配堆内存。字符串文字在编译时已知,可以写入 executable/library 的 ro.data
部分,因此它们不会消耗堆栈或堆 space.
现在,鉴于 Rust 不想在堆上分配值,它基本上被迫将字符串文字视为 &str
:String
s 拥有它们的值并且可以移动和已删除,但是如何删除 ro.data
中的值?你不能真的那样做,所以 &str
是最合适的。
此外,将字符串文字视为 &str
(或者更准确地说,&'static str
)具有所有优点和 none 缺点。它们可以在多个地方使用,可以共享而不用担心使用堆内存,永远不必删除。此外,它们可以随意转换为拥有的 String
,因此始终可以将它们用作 String
,但您只需在需要时支付费用。
我只是问为什么 Rust 决定对字符串文字使用 &str
而不是 String
。 Rust 难道不能自动将字符串文字转换为 String
并将其放在堆上而不是将其放入堆栈吗?
要创建 String
,您必须:
- 在堆上保留一个位置(分配),并且
- 将所需内容从 read-only 位置复制到新分配的区域。
如果像 "foo"
这样的字符串文字同时执行这两种操作,则每个字符串将有效地分配两次:一次在可执行文件中作为 read-only 字符串,另一次在堆上。您不能只引用存储在可执行文件中的原始 read-only 数据。
&str
文字使您可以访问最有效的字符串数据:启动时出现在可执行映像中的数据,由编译器与构成程序的指令一起放置在那里。它指向的数据未存储 在堆栈上 ,stack-allocated 只是 pointer/size 对,就像任何 Rust 切片一样。
将 "foo"
desugar 变成现在拼写的 "foo".to_owned()
会使它变得更慢和更少 space-efficient,并且可能需要 另一个 语法获得 non-allocating &str
。毕竟,您不希望 x == "foo"
分配一个字符串只是为了立即将其丢弃。像 Python 这样的语言通过使它们的字符串不可变来缓解这种情况,这允许它们缓存源代码中提到的字符串。在 Rust 中,变异 String
通常是创建它的全部要点,因此该策略行不通。
要理解其中的原因,请考虑 Rust 想要成为一种系统编程语言。一般来说,这意味着它需要(除其他外)(a)尽可能高效和(b)让程序员完全控制堆内存的分配和释放。 Rust 的一个用例是用于内存非常有限的嵌入式编程。
因此,Rust 不想在并非绝对必要的地方分配堆内存。字符串文字在编译时已知,可以写入 executable/library 的 ro.data
部分,因此它们不会消耗堆栈或堆 space.
现在,鉴于 Rust 不想在堆上分配值,它基本上被迫将字符串文字视为 &str
:String
s 拥有它们的值并且可以移动和已删除,但是如何删除 ro.data
中的值?你不能真的那样做,所以 &str
是最合适的。
此外,将字符串文字视为 &str
(或者更准确地说,&'static str
)具有所有优点和 none 缺点。它们可以在多个地方使用,可以共享而不用担心使用堆内存,永远不必删除。此外,它们可以随意转换为拥有的 String
,因此始终可以将它们用作 String
,但您只需在需要时支付费用。