How to declare a static mutable variable without assignment?

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 an 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?

+6
source share
2 answers

A rate or constant must be assigned upon announcement; they can never be appointed after that.

Staticity should be purely literals; it cannot have any function calls.

At the moment, the constant should be purely literals, but when RFC 911, const fn is implemented, more can be done, you want.

Inside the function, you can have static or const elements, as well as outside the function, and there are no diversity elements (definitions of attributes and types, functions, etc.) inside the function, it purely hides them from external coverage. Therefore, you can usually use let foo .

+7
source

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

For example, 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 pretend it 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, simply create your lazy accessory:

 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 is not thread safe and thus avoids some of Rust's security guarantees, but it will be sufficient for the speed comparison port.

+5
source

Source: https://habr.com/ru/post/986891/


All Articles