Generics 在结构定义中使用静态整数 我试图把一些C++代码移植到生锈。我尝试过很多不同的方法,但没有一种可以编译

Generics 在结构定义中使用静态整数 我试图把一些C++代码移植到生锈。我尝试过很多不同的方法,但没有一种可以编译,generics,rust,Generics,Rust,我想要一个通用模板,它可以处理不同的类型,并且具有可调整的总大小和静态字段(常量表达式)容量: 模板 结构BplusTreeLeaf{ 静态常量16_t容量=(PageSize-16)/(sizeof(KeyType)+sizeof(ValueType)); 钥匙类型钥匙[容量]; ValueType值[容量]; }; 我想从外部访问容量: for(inti=0;i{ 静态容量:u16=($PageSize-16)/(std::mem::size_of:()+std::mem::size_of

我想要一个通用模板,它可以处理不同的类型,并且具有可调整的总大小和静态字段(常量表达式)
容量

模板
结构BplusTreeLeaf{
静态常量16_t容量=(PageSize-16)/(sizeof(KeyType)+sizeof(ValueType));
钥匙类型钥匙[容量];
ValueType值[容量];
};
我想从外部访问容量:

for(inti=0;i
在《铁锈》中似乎没有办法做到这一点,或者至少在我对《铁锈》的理解中:

  • 结构中不允许使用静态,文档告诉我使用宏
  • 只有类型可以在Rust中“模板化”,而不是值或表达式。我甚至不能将总大小作为参数传递给结构定义
就我所知:

macro_rules! BplusTreeLeaf {
    ($KeyType:ident, $ValueType:ident, $PageSize:expr) => {
        static Capacity_: u16 = ($PageSize - 16) / (std::mem::size_of::<$KeyType>() + std::mem::size_of::<$ValueType>());
        struct BplusTreeLeaf_ {
            keys: [$KeyType, ..Capacity_],
            values: [$ValueType, ..Capacity_],
        }
    }
}

BplusTreeLeaf!(u64, u64, 4096)
macro\u规则!BPLUSTERELEAF{
($KeyType:Identit,$ValueType:Identit,$PageSize:expr)=>{
静态容量:u16=($PageSize-16)/(std::mem::size_of:()+std::mem::size_of::());
结构BplusTreeLeaf\u{
密钥:[$KeyType,…容量\],
值:[$ValueType,…容量\],
}
}
}
BplusTreeLeaf!(u64、u64、4096)
编译器生成“向量长度的预期常量expr”,这是不正确的,因为我没有将“mut”用于
容量
,所以它必须是常量表达式。即使它可以工作,
Capacity_
BplusTreeLeaf_
仍将在全局范围/命名空间中


我是否误解了Rust设计中的一些基本元素,还是根本不可能?如果现在不可能,有没有计划作为未来的特征,或者我应该和C++ 11保持一致吗?< /P> < P>这个问题已经过时了,但仍然有效。你可以用板条箱

普通静态变量必须用常量表达式初始化,常量表达式可能包括常量函数。这允许在编译时对它们求值,并将其烘焙到二进制文件中。但是,这带来了许多限制,例如没有堆分配

您希望在程序首次运行时计算该常数。如本例所示,直接从板条箱页面:

lazy_static! {
    static ref HASHMAP: HashMap<u32, &'static str> = {
        let mut m = HashMap::new();
        m.insert(0, "foo");
        m.insert(1, "bar");
        m.insert(2, "baz");
        m
    };
}

fn main() {
    // First access to `HASHMAP` initializes it
    println!("The entry for `0` is \"{}\".", HASHMAP.get(&0).unwrap());

    // Any further access to `HASHMAP` just returns the computed value
    println!("The entry for `1` is \"{}\".", HASHMAP.get(&1).unwrap());
}
lazy\u static!{

static ref HASHMAP:HASHMAP您正在寻找的主要功能被调用。Rust 1.51中提供了基本支持:

struct BplusTreeLeaf{
密钥:[K;CAP],
值:[V;上限],
}
impl BplusTreeLeaf{
常数容量:usize=上限;
}
fn main(){
println!(“{}”,BplusTreeLeaf:::容量);
println!(“{}”,BplusTreeLeaf:::容量);
}
如前所述,您可以为Rust的早期版本创建宏,该宏将创建具有特定容量的一次性类型:

宏\u规则!制作\u页{
($name:ident,$capacity:expr)=>{
结构$name{
密钥:[K;$capacity],
值:[V;$capacity],
}
impl$name{
const CAPACITY:usize=$CAPACITY;
}
}
}
制作叶子!(BplusTreeLeaf16,16);
制作叶子!(BplusTreeLeaf32,32);
fn main(){
println!(“{}”,BplusTreeLeaf16:::容量);
println!(“{}”,BplusTreeLeaf32:::容量);
}
另见:


是的,有很多未实现的功能。编译器给出了“预期常量表达式”错误,因为mem::size\u of是一个普通函数,而不是“constexpr”。好吧,他们将在未来的某个地方,在1.0之后添加“constexpr”和“非类型模板参数”以及“静态成员”在1.0之前,使用这个RFC:(但感谢GitHub问题的链接。你误解了OP想要什么。他们正在寻找。哦,好吧,这是我的错。值得删除答案,还是我应该留下它?你可以更改它,以展示如何使用宏和相关常量实现它。也许接下来是一个假设的例子,说明一旦RFC已经实施了。好吧,我很快会想出办法的。