问题
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?
回答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.
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
.
回答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).
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'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.
来源:https://stackoverflow.com/questions/30145814/how-do-i-declare-a-static-mutable-variable-without-assignment