0

I have named a 3-sized array type Sequence. From objects of this type, the entries of a Vec will successively be calculated by a finite automaton. After the automaton has run, the Vec is guaranteed to either contain the length of Sequence (=3) or in some cases one more than that (=4) items.

I try to use Vec::with_capacity to fit the Vec to the maximum possible memory requirements (=4). To avoid useless allocation and dropping of the Vec, I want to allocate it once before any Sequence object arrives:

type Sequence = [ f64; 3 ];

fn main() {
    let mut accumulator: Vec<f64> = Vec::with_capacity( Sequence.len() + 1 );
    …
}

Of course, this code does not compile, because .len() only works on instances, not the type. But there is no concrete Sequence variable there at this preparatory stage.

I would like to avoid a hard-to-read C-like construct of the form used in:

use std::mem::size_of;
type Sequence = [ f64; 3 ];

fn main() {
    let mut accumulator: Vec<f64> = Vec::with_capacity( size_of::<Sequence>() / size_of::<f64>() + 1 );
}

My type should remain very simple; for generics, I have read a good answer to a similar question here: Can I get a Rust array's length with only a type, not a concrete variable? But I wonder whether there is a simpler way for my quite straightforwart type Sequence than defining a generic trait to get the job done.

For eample, I know that I could define a const and use that, but it seems this would tear apart type information from the type; and if rust allows, I want to avoid that:

const SEQUENCE_LEN: usize = 3;
type Sequence = [ f64; SEQUENCE_LEN ];

fn main() {
    let mut accumulator: Vec<f64> = Vec::with_capacity( SEQUENCE_LEN + 1 );
}

For the same reason of keeping things together when they belong together, I do not want to simply use a literal like in with_capacity(4).

1 Answers1

0

This doesn't strike me as great, but another option is

type Sequence = [f64; 3];

pub fn get_vec() -> Vec<f64> {
    Vec::with_capacity(Sequence::default().len() + 1)
}

In release mode, this compiles down to exactly the same assembly as

type Sequence = [f64; 3];

pub fn get_vec_magic_number() -> Vec<f64> {
    Vec::with_capacity(4)
}
isaactfa
  • 5,461
  • 1
  • 10
  • 24