ski*_*iwi 7 generics default rust
我正在尝试将位向量库实现为练习,但是当我想要为泛型类型参数定义默认值时,我遇到了麻烦.
这是我所拥有的代码的摘录:
extern crate num;
use std::cmp::Eq;
use std::ops::{BitAnd,BitOrAssign,Index,Shl};
use num::{One,Zero,Unsigned,NumCast};
pub trait BitStorage: Sized +
BitAnd<Self, Output = Self> +
BitOrAssign<Self> +
Shl<Self, Output = Self> +
Eq + Zero + One + Unsigned + NumCast + Copy {}
impl<S> BitStorage for S where S: Sized +
BitAnd<S, Output = S> +
BitOrAssign<S> +
Shl<S, Output = S> +
Eq + Zero + One + Unsigned + NumCast + Copy {}
pub struct BitVector<S: BitStorage = usize> {
data: Vec<S>,
capacity: usize
}
impl<S: BitStorage> BitVector<S> {
pub fn with_capacity(capacity: usize) -> BitVector<S> {
let len = (capacity / (std::mem::size_of::<S>() * 8)) + 1;
BitVector { data: vec![S::zero(); len], capacity: capacity }
}
//...
}
Run Code Online (Sandbox Code Playgroud)
我想用它如下:
let vec = BitVector::with_capacity(1024);
Run Code Online (Sandbox Code Playgroud)
但是我收到编译器错误:
lib.rs:225:24:225:48错误:无法推断出足够的类型信息
_; 需要输入注释或通用参数绑定[E0282]
lib.rs:225 let vec_1000 = BitVector :: with_capacity(1000);
^ ~~~~~~~~~~~~~~~~~~~~~~~
lib.rs:225:24:225:48求助:跑rustc --explain E0282看详细说明
为了让多一点背景下的代码,当前有效的类型BitStorage包括(但不限于*) ,u8,,u16 和.u32u64usize
(*)u128如果您实现该类型的所有特征,我认为您可以编写自定义实现(仅作为示例).
在谷歌搜索该问题后,我发现RFC 213似乎还不稳定.但另一方面HashMap目前在稳定使用默认值,所以它应该工作,对吧?
对默认类型参数的支持仍然受到限制,但是在某些情况下可以使用。当使用struct带有默认类型参数的a来指定变量的类型时,将使用默认类型参数来定义变量的类型:
// the type of vec is BitVector<usize>, so the type of
// BitVector::with_capacity(1024) is correctly inferred
let vec: BitVector = BitVector::with_capacity(1024);
Run Code Online (Sandbox Code Playgroud)
但是另一方面,
HashMap当前处于稳定状态的是使用默认值,因此它应该可以工作,对吗?
查看HashMap源代码,我们可以看到方法new和和with_capacity是RandomState针对S参数实现的,并且不依赖于中的默认类型参数HashMap。所有其他方法都以通用方式实现S,包括的其他“构造函数”方法with_hasher。
您可以编写类似的内容:
impl BitVector<usize> {
pub fn default_with_capacity(capacity: usize) -> BitVector<usize> {
// type is inferred
Self::with_capacity(capacity)
}
}
impl<S: BitStorage> BitVector<S> {
pub fn with_capacity(capacity: usize) -> BitVector<S> {
let len = (capacity / (std::mem::size_of::<S>() * 8)) + 1;
BitVector {
data: vec![S::zero(); len],
capacity: capacity,
}
}
// ...
}
// create with "default" BitStore
let vec = BitVector::default_with_capacity(1024);
// specify BitStore
let vec = BitVector::<u32>::with_capacity(1024);
Run Code Online (Sandbox Code Playgroud)