如何在没有赋值的情况下声明静态可变变量?

时间:2023-01-12 20:54:23

I tried the following

我尝试了以下内容

struct mbuf
{
  cacheline: *mut [u64],               // great amount of rows follows below
  // ..........
}
static mut arr: [mbuf; 32];                // Q1 my main aim
// something as before but using Vec;      // Q2 also main aim

fn main() {
 // let static mut arr: [mbuf; 32];        // Q3 also doesn't work
 // static mut arr: [mbuf; 32];            // Q3 also doesn't work
}

and got error

并得到错误

src/main.rs:74:29: 74:30 error: expected one of `+` or `=`, found `;`
src/main.rs:74   static mut arr: [mbuf; 32];
                                           ^

Q1,Q2,Q3 - Is it possible and how?

Q1,Q2,Q3 - 是否可能以及如何?

2 个解决方案

#1


A static or constant must be assigned when declared; they can never be assigned to after that.

声明时必须分配静态或常量;在那之后他们永远不会被分配。

A static must be purely literals; it cannot have any function calls.

静态必须纯粹是文字;它不能有任何函数调用。

A constant must at present be purely literals, but when RFC 911, const fn is implemented it will be possible to do things more like how you desire.

目前,常量必须是纯粹的文字,但是当RFC 911,const fn被实现时,可以更像你想要的东西。

Inside a function, you can have static or const items, just as outside a function, and there is no difference—placing items (trait and type definitions, functions, &c.) inside a function purely hides them from the outside scope. Therefore you typically might as well use let foo.

在函数内部,您可以使用静态或常量项,就像在函数外部一样,并且没有区别 - 函数内部的放置项(特征和类型定义,函数等)纯粹将它们从外部范围隐藏。因此,您通常也可以使用let foo。

#2


You can use lazy-static to initialize the static array on first access, even though it might incur a minimal overhead (it seems to invoke Once::call_once every time you access the static variable).

您可以使用lazy-static在第一次访问时初始化静态数组,即使它可能会产生最小的开销(每次访问静态变量时它似乎都会调用Once :: call_once)。

For example, Cargo.toml:

例如,Cargo.toml:

[package]
name = "arr"
version = "0.0.1"

[[bin]]
name = "arr"
path = "arr.rs"

[dependencies]
lazy_static = "*"

arr.rs:

#[macro_use]
extern crate lazy_static;
use std::mem;
use std::ptr;

#[derive(Debug)]
struct Mbuf {
    cacheline: *mut u64,
}
// Let's pretend it's thread-safe to appease the lazy_static! constrains.
unsafe impl Sync for Mbuf { }

lazy_static! {
    static ref ARR: [Mbuf; 32] = {
        let mut tmp: [Mbuf; 32] = unsafe { mem::uninitialized() };
        for idx in 0..tmp.len() {
            tmp[idx] = Mbuf { cacheline: ptr::null_mut() };
        }
        tmp
    };
}

fn main() {
    println!("{:?}", *ARR);
}

Alternatively, just make your own lazy accessor:

或者,只需创建自己的懒惰访问器:

use std::mem;
use std::ptr;

#[derive(Debug)]
struct Mbuf {
    cacheline: *mut u64,
}

static mut ARR: Option<[Mbuf; 32]> = None;
fn arr() -> &'static mut [Mbuf; 32] {
    unsafe {
        if ARR.is_none() {
            let mut tmp: [Mbuf; 32] = mem::uninitialized();
            for idx in 0..tmp.len() {
                tmp[idx] = Mbuf { cacheline: ptr::null_mut() };
            }
            ARR = Some(tmp);
        }
        mem::transmute(ARR.as_mut().unwrap())
    }
}

fn main() {
    println!("{:?}", arr());
}

Needless to say, this code isn't thread-safe and thus shuns some of the Rust safety guarantees, but for a speed comparison port it shall suffice.

不用说,这段代码不是线程安全的,因此避免了一些Rust安全保证,但对于速度比较端口来说就足够了。

#1


A static or constant must be assigned when declared; they can never be assigned to after that.

声明时必须分配静态或常量;在那之后他们永远不会被分配。

A static must be purely literals; it cannot have any function calls.

静态必须纯粹是文字;它不能有任何函数调用。

A constant must at present be purely literals, but when RFC 911, const fn is implemented it will be possible to do things more like how you desire.

目前,常量必须是纯粹的文字,但是当RFC 911,const fn被实现时,可以更像你想要的东西。

Inside a function, you can have static or const items, just as outside a function, and there is no difference—placing items (trait and type definitions, functions, &c.) inside a function purely hides them from the outside scope. Therefore you typically might as well use let foo.

在函数内部,您可以使用静态或常量项,就像在函数外部一样,并且没有区别 - 函数内部的放置项(特征和类型定义,函数等)纯粹将它们从外部范围隐藏。因此,您通常也可以使用let foo。

#2


You can use lazy-static to initialize the static array on first access, even though it might incur a minimal overhead (it seems to invoke Once::call_once every time you access the static variable).

您可以使用lazy-static在第一次访问时初始化静态数组,即使它可能会产生最小的开销(每次访问静态变量时它似乎都会调用Once :: call_once)。

For example, Cargo.toml:

例如,Cargo.toml:

[package]
name = "arr"
version = "0.0.1"

[[bin]]
name = "arr"
path = "arr.rs"

[dependencies]
lazy_static = "*"

arr.rs:

#[macro_use]
extern crate lazy_static;
use std::mem;
use std::ptr;

#[derive(Debug)]
struct Mbuf {
    cacheline: *mut u64,
}
// Let's pretend it's thread-safe to appease the lazy_static! constrains.
unsafe impl Sync for Mbuf { }

lazy_static! {
    static ref ARR: [Mbuf; 32] = {
        let mut tmp: [Mbuf; 32] = unsafe { mem::uninitialized() };
        for idx in 0..tmp.len() {
            tmp[idx] = Mbuf { cacheline: ptr::null_mut() };
        }
        tmp
    };
}

fn main() {
    println!("{:?}", *ARR);
}

Alternatively, just make your own lazy accessor:

或者,只需创建自己的懒惰访问器:

use std::mem;
use std::ptr;

#[derive(Debug)]
struct Mbuf {
    cacheline: *mut u64,
}

static mut ARR: Option<[Mbuf; 32]> = None;
fn arr() -> &'static mut [Mbuf; 32] {
    unsafe {
        if ARR.is_none() {
            let mut tmp: [Mbuf; 32] = mem::uninitialized();
            for idx in 0..tmp.len() {
                tmp[idx] = Mbuf { cacheline: ptr::null_mut() };
            }
            ARR = Some(tmp);
        }
        mem::transmute(ARR.as_mut().unwrap())
    }
}

fn main() {
    println!("{:?}", arr());
}

Needless to say, this code isn't thread-safe and thus shuns some of the Rust safety guarantees, but for a speed comparison port it shall suffice.

不用说,这段代码不是线程安全的,因此避免了一些Rust安全保证,但对于速度比较端口来说就足够了。