常量和静态变量有什么区别,我应该选择哪个? [英] What is the difference between a constant and a static variable and which should I choose?

查看:42
本文介绍了常量和静态变量有什么区别,我应该选择哪个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从 RFC 246 了解到这一点:

  • 常量声明常量值.这些代表一个值,而不是内存地址.这是最常见的事情,并且会在几乎所有情况下取代我们今天所知道的 static.
  • statics 声明全局变量.这些代表一个内存地址.它们很少使用:主要用例是全局锁、全局原子计数器以及与传统 C 库的接口.
  • 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.
  • 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.

当我尝试维护一张表时,我不知道这两者之间的实际区别是什么.

I don't know what is actually different between the two when I try to maintain a table.

我应该选择哪一个?

推荐答案

可变性

Rust 中的 constant 是不可变的.您既不能重新分配也不能修改它:

Mutability

A constant in Rust is immutable. 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
}

static 变量 是可变的,因此可以修改或重新分配.请注意,编写/修改全局 static 变量是不安全的,因此需要一个 unsafe 块:

A static variable can be mutable and therefore can either be modified or reassigned. Note that writing/modifying a global static variable is unsafe and therefore needs an unsafe block:

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 的地方)将直接被该值替换.

Occurrences

When you compile a binary, all const "occurrences" (where you use that const in your source code) will be replaced by that value directly.

statics 将在您的二进制文件中有一个专门的部分,它们将被放置在其中(BSS 部分,请参阅 C 和 C++ 中的静态变量存储在哪里? 了解更多信息).

statics 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).

总而言之,尽可能坚持使用 const.如果不可能,因为您需要在程序中使用非const 方法稍后初始化变量,请使用 lazy_static!.

All in all, stick to a const whenever possible. When not possible, because you need to initialize a variable later in the program of with non-const methods, use lazy_static!.

虽然 conststatic 都可以使用内部可变性,但你永远不应该用 const 来做.举个例子

While both const and static can use interior mutability you should never ever do it with a 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

使用clippy时,会显示以下两个警告:

When using clippy, it will show the two following warnings:

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

这篇关于常量和静态变量有什么区别,我应该选择哪个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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