[英]What is the difference between a constant and a static variable and which should I choose?
我从RFC 246知道这一点:
- 常量声明常量值。 这些代表一个值,而不是内存地址。 这是最常见的事情,几乎在所有情况下都会取代我们今天所知道的
static
。- 静态声明全局变量。 这些代表一个内存地址。 它们很少使用:主要用例是全局锁、全局原子计数器以及与遗留 C 库的接口。
当我尝试维护一张桌子时,我不知道两者之间实际上有什么不同。
我应该选择哪一个?
Rust 中的const
ant 是不可变的。 您既不能重新分配也不能修改它:
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
}
static
变量可以是可变的,因此可以修改或重新分配。 请注意,写入/修改全局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;
}
}
当你编译一个二进制文件时,所有的const
“出现”(你在源代码中使用该const
地方)将直接被该值替换。
static
将在您的二进制文件中有一个专门的部分,它们将被放置在其中( BSS 部分,请参阅C 和 C++ 中静态变量存储在哪里?了解更多信息)。
总而言之,尽可能坚持使用const
。 如果不可能,因为您需要在使用非const
方法的程序中稍后初始化变量,请使用lazy_static!
.
虽然const
和static
都可以使用内部可变性,但您永远不应该使用 const 来这样做。 这是一个例子
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();
}
这在没有任何警告的情况下编译得很好,但会导致不必要的行为。 输出:
static: 3
const: 0
使用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
如果您的变量不打算更改,则没有太大的实际区别。
常量在编译时内联,这意味着它们被复制到它们使用的每个位置,因此通常更有效,而静态引用内存中的唯一位置,更像是全局变量。
常量是......常量而静态,虽然仍然是全局的,但可以是可变的。
static
vs const
const
:
static
一样查找地址 static
:
例子:
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);
}
}
static
的主要目的是允许函数控制在调用时记住的内部值,但不能被主应用程序代码访问。 它类似于类变量,而不是其他语言中的实例变量。 C 和 PHP 以及许多其他语言也有这个概念。
示例:您想跟踪函数被调用的次数并有一种重置内部计数器的方法:
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.