const变量和静态变量之间有什么区别?我应该选择哪个?

Aur*_*ier 4 static const rust

我从RFC 246中知道这一点:

  • 常量声明常量值.它们代表一个值,而不是内存地址.这是人们可以达到的最常见的事情,并且static几乎在所有情况下我们今天都会知道它.
  • 静态声明全局变量.这些代表一个内存地址.它们很少使用:主要用例是全局锁,全局原子计数器以及与传统C库的接口.

当我试图维护一张桌子时,我不知道两者之间究竟有什么不同.

我应该选择哪一个?

Den*_*ret 9

如果您的变量不打算更改,则没有太大的实际区别。

常量在编译时内联,这意味着它们被复制到它们使用的每个位置,因此通常更有效,而静态引用内存中的唯一位置,更像是全局变量。

常量是......常量而静态,虽然仍然是全局的,但可以是可变的。


hel*_*low 9

可变性

constRust中的变量是不可变的.你既不能重新分配也不能修改它:

struct Foo(u32);

const FOO: Foo = Foo(5);

fn main() {
    FOO = Foo(1); //illegal
    FOO.0 = 2; //illegal
}
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

出现次数

编译二进制文件时,所有const"出现"(在const源代码中使用它的位置)将直接替换为该值.

statics将在二进制文件中放置一个专门的部分(BSS部分,请参阅C和C++中存储的静态变量在哪里?以获取更多信息).


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

  • @TimDiekmann 虽然我同意您的建议的精神,但我认为这太高级了。在某些情况下,`const` 会*工作*,但与 `static` 相比性能很差,例如 [OP 链接到的代码](https://github.com/kennytm/qrcode-rust/blob/ d10dad26284fc938c470236b7221460e1a5f99e9/src/ec.rs#L238-L273)。 (3认同)

Wil*_*een 5

铁锈staticvsconst

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

1403 次

最近记录:

6 年,10 月 前