Rust:无需具体变量,如何从命名数组类型获取长度?
我定义了一个长度为3的数组类型Sequence。有限状态机会基于该类型的对象依次计算Vec的元素,运行结束后,Vec的元素数量保证要么等于Sequence的长度(即3),要么比其多1个(即4)。
我尝试使用Vec::with_capacity为Vec分配满足最大内存需求的空间(即4)。为避免无用的内存分配和Vec销毁操作,我希望在任何Sequence对象创建前就完成一次分配:
type Sequence = [ f64; 3 ]; fn main() { let mut accumulator: Vec<f64> = Vec::with_capacity( Sequence.len() + 1 ); … }
显然这段代码无法编译,因为.len()仅适用于实例而非类型,但在这个准备阶段并没有具体的Sequence变量。
我希望避免类似以下这种可读性差的C风格写法:
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 ); }
我的类型应该保持简洁;针对泛型的情况,我已在Stack Overflow上看到过类似问题的优质解答,但我想知道对于Sequence这种简单类型,是否有比定义泛型 trait更简洁的实现方式。
例如,我知道可以定义一个const常量来实现,但这会将类型信息与类型本身拆分,如果Rust允许,我希望避免这种方式:
const SEQUENCE_LEN: usize = 3; type Sequence = [ f64; SEQUENCE_LEN ]; fn main() { let mut accumulator: Vec<f64> = Vec::with_capacity( SEQUENCE_LEN + 1 ); }
出于同样的“相关内容应保持关联”的原因,我也不想直接使用字面量,比如with_capacity(4)。
利用数组自带的关联常量(Rust 1.59+)
从Rust 1.59版本开始,数组类型原生支持LEN关联常量,可以直接通过类型访问长度,完美贴合你“类型与长度关联”的需求:
type Sequence = [f64; 3]; fn main() { // 两种写法都可行,后者更简洁 let mut accumulator: Vec<f64> = Vec::with_capacity(<Sequence>::LEN + 1); // let mut accumulator = Vec::with_capacity(Sequence::LEN + 1); }
旧版本兼容方案:使用LengthAtMost32 trait
如果你的Rust版本低于1.59,可以借助标准库中为短数组提供的LengthAtMost32 trait,它同样暴露了LEN关联常量:
use std::array::LengthAtMost32; type Sequence = [f64; 3]; fn main() { let mut accumulator: Vec<f64> = Vec::with_capacity(<Sequence as LengthAtMost32>::LEN + 1); }
自定义封装式常量(无版本依赖)
如果不想受版本限制,还可以把长度常量封装在和类型关联的模块中,既保持关联性又避免全局常量分散:
type Sequence = [f64; SequenceMeta::LEN]; mod SequenceMeta { pub const LEN: usize = 3; } fn main() { let mut accumulator: Vec<f64> = Vec::with_capacity(SequenceMeta::LEN + 1); }
内容的提问来源于stack exchange,提问作者Bernhard Bodenstorfer

