除了非文字进入堆的事实之外,文字和非文字之间有什么区别? [英] What is the difference between literals and non-literals, other than the fact that non-literals go into the heap?

查看:56
本文介绍了除了非文字进入堆的事实之外,文字和非文字之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对文字和非文字之间的区别感到困惑(堆上的那些,我不知道它们叫什么).例如,String类型为例:

I am confused by the difference between literals and non-literals (the ones that go on the heap, I do not know what they are called). For example, taking the String type as an example:

我们已经看到了字符串字面量,其中一个字符串值是硬编码的进入我们的程序.字符串文字很方便,但它们不是始终适用于您想要使用文本的每种情况.一原因是它们是不可变的....

We’ve already seen string literals, where a string value is hardcoded into our program. String literals are convenient, but they aren’t always suitable for every situation in which you want to use text. One reason is that they’re immutable. ...

我不明白上面的内容,因为我们已经看过这样的例子:

I do not understand the above, as we have already seen an example like this:

let mut a = "a"; // this is String literal here, so sitting on the stack
a = "b";
println!("a is being changed to...{}", a); // this is the same String literal sitting on the stack?

很明显,文字在 Rust 中是可变的.除了文字进入堆栈,而非文字进入堆这一事实之外,两者之间有什么区别?

Clearly literals can be mutable in Rust. What is the difference between the two, other than the fact that literals go into the stack, while non-literals go into the heap?

我试图理解为什么我不应该只在我的代码中使用可变文字,因为堆栈比堆快.

I am trying to understand why I shouldn't just use mutable literals in my code, considering that the stack is faster than the heap.

// a is mutable literal
let mut a = "a";
a = "b";
// b is mutable 'non-literal'
let mut b = String::from("a");
b = String::from("b");

推荐答案

显然文字在 Rust 中是可变的

Clearly literals can be mutable in Rust

首先,您需要了解什么是文字.字面量永远是可变的,因为它们字面地写在源代码中并编译成最终的二进制文件.您的程序不会更改您的源代码!

First, you need to understand what a literal is. Literals are never mutable because they are literally written in the source code and compiled into the final binary. Your program does not change your source code!

显示您不能修改文字的示例:

An example showing that you cannot modify a literal:

fn main() {
    1 += 2;
}

error[E0067]: invalid left-hand side expression
 --> src/main.rs:2:5
  |
2 |     1 += 2;
  |     ^ invalid expression for left-hand side

另一方面,可以将文字复制到变量中,然后可以更改变量,但我们仍然没有改变文字1:

On the other hand, a literal can be copied into a variable and then the variable can be changed, but we still are not mutating the literal 1:

fn main() {
    let mut a = 1;
    a += 2;
}

老实说,我不知道我会怎么称呼非文字".文字是一种特定类型的表达式,但是程序中除了表达式之外还有其他类型的东西.这有点像说猫"和非猫"——第二组是否包括狗、蘑菇、沙子和/或情绪?

To be honest, I don't know what I would call a "non-literal". A literal is a specific type of expression, but there are other types of things in a program besides expressions. It's kind of like saying "cats" and "non-cats" — does that second group include dogs, mushrooms, sand, and/or emotions?

文字进入堆栈,而非文字进入堆的事实

the fact that literals go into the stack, while non-literals go into the heap

这两个品质并没有直接关系.在堆栈中放置非文字很容易:

Those two qualities aren't really directly related. It's pretty easy to have non-literals on the stack:

fn main() {
    let a = 1;
    let b = 2;
    let c = a + b;
}

所有三个变量都在堆栈上,但源代码中的任何地方都没有文字 3.

All three variables are on the stack, but there is no literal 3 anywhere in the source code.

现在,Rust 不允许文字值进行堆分配,但这是一种特定于语言的事情,可能会随着时间的推移而改变.其他语言可能允许.

Right now, Rust doesn't allow for a literal value to have a heap-allocation, but that's a language-specific thing that might change over time. Other languages probably allow it.

事实上,你必须在 Rust 中特意将一些东西放到堆上.BoxVecString 等类型都调用函数在堆上分配空间.代码使用堆内存的唯一方法是使用这些类型、使用它们的其他类型或以其他方式分配堆内存的类型.

In fact, you have to go out of your way in Rust to put something on the heap. Types like Box, Vec, and String all call functions to allocate space on the heap. The only way for your code to use heap memory is if you use these types, other types that use them, or types which allocate heap memory in some other way.

我们不能使用 String 文字数据类型的原因是什么

What is the reason we cannot use String literal data-type

没有 String 文字——没有.源代码 "foo" 创建了一个 &'static str 类型的文字.这些是截然不同的类型.具体来说,Rust 语言可以在没有堆的环境中工作;没有文字可以假设可以分配内存.

There is no String literal — none. The source code "foo" creates a literal of type &'static str. These are drastically different types. Specifically, the Rust language can work in environments where there is no heap; no literal could assume that it's possible to allocate memory.

必须专门使用String::from()

String::from&str 转换为 String;它们是两种不同的类型,必须进行转换.

String::from converts from &str to a String; they are two different types and a conversion must be performed.

显然,根据示例,在我的代码中,两者都是可变的

Clearly, as per the example, in my code, both can be mutable

,他们不能.不可能从 let mut foo = "a" 开始修改那个 "a" 变成其他任何东西.您可以更改 foo 指向的内容:

No, they cannot. It is impossible to start with let mut foo = "a" and modify that "a" to become anything else. You can change what that foo points to:

let mut foo = "a";

                foo
     +-----------+
     |
     |
 +---v---+              
 |       |              
 |  "a"  |           
 |       |     
 +-------+         

foo = "b";

                  foo
                   +----------+
                              |
                              |
   +-------+              +---v---+
   |       |              |       |
   |  "a"  |              |  "b"  |
   |       |              |       |
   +-------+              +-------+

"a""b" 永远不会改变,而是 foo 指向 .

Neither "a" nor "b" ever change, but what foo points to does.

并非特定于 Rust.例如,Java 和 C# 字符串也是不可变的,但您可以重新分配一个变量以指向不同的不可变字符串.

This isn't specific to Rust. Java and C# strings are also immutable, for example, but you can reassign a variable to point to a different immutable string.

另见:

这篇关于除了非文字进入堆的事实之外,文字和非文字之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆