[英]What is the difference between a constant and a static variable and which should I choose?
I know this from RFC 246 :我从RFC 246知道这一点:
- constants declare constant values .
常量声明常量值。 These represent a value, not a memory address.
这些代表一个值,而不是内存地址。 This is the most common thing one would reach for and would replace
static
as we know it today in almost all cases.这是最常见的事情,几乎在所有情况下都会取代我们今天所知道的
static
。- statics declare global variables .
静态声明全局变量。 These represent a memory address.
这些代表一个内存地址。 They would be rarely used: the primary use cases are global locks, global atomic counters, and interfacing with legacy C libraries.
它们很少使用:主要用例是全局锁、全局原子计数器以及与遗留 C 库的接口。
I don't know what is actually different between the two when I try to maintain a table.当我尝试维护一张桌子时,我不知道两者之间实际上有什么不同。
Which one should I choose?我应该选择哪一个?
A const
ant in Rust is immutable. Rust 中的
const
ant 是不可变的。 You neither can reassign nor modify it:您既不能重新分配也不能修改它:
struct Foo(u32);
const FOO: Foo = Foo(5);
const mut FOO: Foo = Foo(5); // illegal
fn main() {
FOO = Foo(1); //illegal
FOO.0 = 2; //illegal
}
A static
variable can be mutable and therefore can either be modified or reassigned. static
变量可以是可变的,因此可以修改或重新分配。 Note that writing/modifying a global static
variable is unsafe and therefore needs an unsafe
block:请注意,写入/修改全局
static
变量是不安全的,因此需要一个unsafe
块:
struct Foo(u32);
static FOO: Foo = Foo(5);
static mut FOO_MUT: Foo = Foo(3);
fn main() {
unsafe {
FOO = Foo(1); //illegal
FOO.0 = 2; //illegal
FOO_MUT = Foo(1);
FOO_MUT.0 = 2;
}
}
When you compile a binary, all const
"occurrences" (where you use that const
in your source code) will be replaced by that value directly.当你编译一个二进制文件时,所有的
const
“出现”(你在源代码中使用该const
地方)将直接被该值替换。
static
s will have a dedicated section in your binary where they will be placed (the BSS section , see Where are static variables stored in C and C++? for further information). static
将在您的二进制文件中有一个专门的部分,它们将被放置在其中( BSS 部分,请参阅C 和 C++ 中静态变量存储在哪里?了解更多信息)。
All in all, stick to a const
whenever possible.总而言之,尽可能坚持使用
const
。 When not possible, because you need to initialize a variable later in the program of with non- const
methods, use lazy_static!
如果不可能,因为您需要在使用非
const
方法的程序中稍后初始化变量,请使用lazy_static!
. .
While both const
and static
can use interior mutability you should never ever do it with a const.虽然
const
和static
都可以使用内部可变性,但您永远不应该使用 const 来这样做。 Here's an example这是一个例子
use std::sync::atomic::{AtomicU32, Ordering};
static STATIC: AtomicU32 = AtomicU32::new(0);
const CONST: AtomicU32 = AtomicU32::new(0);
fn print() {
println!("static: {}", STATIC.load(Ordering::Relaxed));
println!("const: {}", CONST.load(Ordering::Relaxed));
}
fn main() {
STATIC.store(3, Ordering::Relaxed);
CONST.store(3, Ordering::Relaxed);
print();
}
This compiles fine without any warnings, but leads to unwanted behavoir.这在没有任何警告的情况下编译得很好,但会导致不必要的行为。 Output:
输出:
static: 3
const: 0
When using clippy, it will show the two following warnings:使用clippy时,会显示以下两个警告:
warning: a `const` item should never be interior mutable
--> src/main.rs:4:1
|
4 | const CONST: AtomicU32 = AtomicU32::new(0);
| -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| make this a static item (maybe with lazy_static)
|
= note: `#[warn(clippy::declare_interior_mutable_const)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#declare_interior_mutable_const
warning: a `const` item with interior mutability should not be borrowed
--> src/main.rs:8:27
|
8 | println!("const: {}", CONST.load(Ordering::Relaxed));
| ^^^^^
|
= note: `#[warn(clippy::borrow_interior_mutable_const)]` on by default
= help: assign this const to a local or static variable, and use the variable here
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const
warning: a `const` item with interior mutability should not be borrowed
--> src/main.rs:13:5
|
13 | CONST.store(3, Ordering::Relaxed);
| ^^^^^
|
= help: assign this const to a local or static variable, and use the variable here
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#borrow_interior_mutable_const
There's not much practical difference if your variable isn't intended to change.如果您的变量不打算更改,则没有太大的实际区别。
Constants are inlined at compilation, which means they're copied to every location they're used, and thus are usually more efficient, while statics refer to a unique location in memory and are more like global variables.常量在编译时内联,这意味着它们被复制到它们使用的每个位置,因此通常更有效,而静态引用内存中的唯一位置,更像是全局变量。
Constants are... constant while statics, while still global, can be mutable.常量是......常量而静态,虽然仍然是全局的,但可以是可变的。
static
vs const
static
vs const
const
: const
:
static
static
一样查找地址static
: static
:
Example:例子:
static CDF: i32 = 100;
const ABC: i32 = 50;
fn main() {
println!("{}", CDF); // compiler will put in a load instruction here for the static address
println!("{}", ABC); // compiler will put the value 50 here directly
// statics can be mutable
static mut HI: &str = "hi";
// however using mut static is unsafe
unsafe {
HI = "HITHERE";
}
unsafe {
println!("{}", HI);
}
}
The main purpose of static
is to allow functions to control an internal value that is remembered across calls, but not be accessible by the main application code. static
的主要目的是允许函数控制在调用时记住的内部值,但不能被主应用程序代码访问。 It is similar to Class variables as opposed to Instance variables in other languages.它类似于类变量,而不是其他语言中的实例变量。 Also C and PHP and many other languages have this concept.
C 和 PHP 以及许多其他语言也有这个概念。
Example: you want to track how many times a function is called and have a way of resetting the internal counter:示例:您想跟踪函数被调用的次数并有一种重置内部计数器的方法:
fn counter(reset: bool) -> i32 {
static mut Count: i32 = 0;
unsafe {
if reset {
Count = 0;
}
Count += 1;
return Count;
}
}
println!("{}",counter(true));
println!("{}",counter(false));
println!("{}",counter(false));
//println!("{}", Count); // Illegal
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.