简体   繁体   English

为什么 Rust 中的字符串文字是 &str 而不是 String?

[英]Why are string literals &str instead of String in Rust?

I'm just asking why Rust decided to use &str for string literals instead of String .我只是问为什么 Rust 决定对字符串文字使用&str而不是String Isn't it possible for Rust to just automatically convert a string literal to a String and put it on the heap instead of putting it into the stack?是不是有可能生锈字符串文字只是自动转换为String ,并把它放在堆,而不是把它入堆栈的?

To understand the reasoning, consider that Rust wants to be a systems programming language.要理解推理,请考虑 Rust 想成为一种系统编程语言。 In general, this means that it needs to be (among other things) (a) as efficient as possible and (b) give the programmer full control over allocations and deallocations of heap memory.一般来说,这意味着它需要(除其他外)(a)尽可能高效,(b)让程序员完全控制堆内存的分配和释放。 One use case for Rust is for embedded programming where memory is very limited. Rust 的一个用例是用于内存非常有限的嵌入式编程。

Therefore, Rust does not want to allocate heap memory where this is not strictly necessary.因此,Rust 不想在并非绝对必要的情况下分配堆内存。 String literals are known at compile time and can be written into the ro.data section of an executable/library, so they don't consume stack or heap space.字符串文字在编译时是已知的,可以写入可执行文件/库的ro.data部分,因此它们不会消耗堆栈或堆空间。

Now, given that Rust does not want to allocate the values on the heap, it is basically forced to treat string literals as &str : String s own their values and can be moved and dropped, but how do you drop a value that is in ro.data ?现在,鉴于 Rust 不想在堆上分配值,它基本上被迫将字符串文字视为&strString拥有它们的值并且可以移动和删除,但是如何删除ro.data的值ro.data You can't really do that, so &str is the perfect fit.你真的不能那样做,所以&str是完美的选择。

Furthermore, treating string literals as &str (or, more accurately &'static str ) has all the advantages and none of the disadvantages.此外,将字符串文字视为&str (或更准确地说是&'static str )具有所有优点,但没有任何缺点。 They can be used in multiple places, can be shared without worrying about using heap memory and never have to be deleted.它们可以在多个地方使用,可以共享而不必担心使用堆内存并且永远不必删除。 Also, they can be converted to owned String s at will, so having them available as String is always possible, but you only pay the cost when you need to.此外,它们可以随意转换为拥有的String ,因此始终可以将它们作为String使用,但您只需在需要时支付费用。

To create a String , you have to:要创建String ,您必须:

  • reserve a place on the heap (allocate), and在堆上保留一个位置(分配),和
  • copy the desired content from a read-only location to the freshly allocated area.将所需内容从只读位置复制到新分配的区域。

If a string literal like "foo" did both, every string would effectively be allocated twice: once inside the executable as the read-only string, and the other time on the heap.如果像"foo"这样的字符串字面量两者都做,那么每个字符串实际上会被分配两次:一次在可执行文件中作为只读字符串,另一次在堆中。 You simply couldn't just refer to the original read-only data stored in the executable.您不能仅仅引用存储在可执行文件中的原始只读数据。

&str literals give you access to the most efficient string data: the one present in the executable image on startup, put there by the compiler along with the instructions that make up the program. &str文字使您可以访问最有效的字符串数据:启动时出现在可执行映像中的数据,由编译器与构成程序的指令一起放在那里。 The data it points to is not stored on the stack , what is stack-allocated is just the pointer/size pair, as is the case with any Rust slice.它指向的数据没有存储在堆栈中,堆栈分配的只是指针/大小对,就像任何 Rust 切片的情况一样。

Making "foo" desugar into what is now spelled "foo".to_owned() would make it slower and less space-efficient, and would likely require another syntax to get a non-allocating &str ."foo" desugar 变成现在拼写为"foo".to_owned()会使其变慢且空间效率较低,并且可能需要另一种语法来获得非分配&str After all, you don't want x == "foo" to allocate a string just to throw it away immediately.毕竟,您不希望x == "foo"分配一个字符串只是为了立即将其丢弃。 Languages like Python alleviate this by making their strings immutable, which allows them to cache strings mentioned in the source code.像 Python 这样的语言通过使它们的字符串不可变来缓解这个问题,这允许它们缓存源代码中提到的字符串。 In Rust mutating String is often the whole point of creating it, so that strategy wouldn't work.在 Rust 中,改变String通常是创建它的重点,因此该策略不起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM