无法推断默认泛型类型参数
Default generic type parameter cannot be inferred
我正在尝试实现位向量库作为练习,但是当我想为泛型类型参数定义默认值时遇到了麻烦。
这是我的代码的摘录:
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 }
}
//...
}
我想按如下方式使用它:
let vec = BitVector::with_capacity(1024);
但是我得到一个编译器错误:
lib.rs:225:24: 225:48 error: unable to infer enough type information about _
; type annotations or generic parameter binding required [E0282]
lib.rs:225 let vec_1000 = BitVector::with_capacity(1000);
^~~~~~~~~~~~~~~~~~~~~~~~
lib.rs:225:24: 225:48 help: run rustc --explain E0282
to see a detailed explanation
为了给代码提供更多上下文,BitStorage
当前有效的类型包括(但不限于*)u8
、u16
、u32
, u64
和 usize
.
(*) 如果您实现该类型的所有特征,我认为您可以编写自定义 u128
实现(仅作为示例)。
在谷歌搜索这个问题后,我发现 RFC 213 which does not seem to be stable yet. However on the other hand HashMap 目前稳定版正在使用默认值,所以它应该可以工作,对吧?
对默认类型参数的支持仍然有限,但在某些情况下可以使用。当使用带有默认类型参数的struct
来指定变量的类型时,默认类型参数用于定义变量的类型:
// 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);
However on the other hand HashMap
currently on stable is using default values, so it should be working, right?
查看HashMap
源代码,我们可以看到方法new
和with_capacity
是通过RandomState
实现的S
参数和不依赖于 HashMap
中的默认类型参数。所有其他方法都在 S
上实现为通用方法,包括其他 "constructor" 方法,如 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);
我正在尝试实现位向量库作为练习,但是当我想为泛型类型参数定义默认值时遇到了麻烦。
这是我的代码的摘录:
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 }
}
//...
}
我想按如下方式使用它:
let vec = BitVector::with_capacity(1024);
但是我得到一个编译器错误:
lib.rs:225:24: 225:48 error: unable to infer enough type information about
_
; type annotations or generic parameter binding required [E0282]
lib.rs:225 let vec_1000 = BitVector::with_capacity(1000);
^~~~~~~~~~~~~~~~~~~~~~~~
lib.rs:225:24: 225:48 help: runrustc --explain E0282
to see a detailed explanation
为了给代码提供更多上下文,BitStorage
当前有效的类型包括(但不限于*)u8
、u16
、u32
, u64
和 usize
.
(*) 如果您实现该类型的所有特征,我认为您可以编写自定义 u128
实现(仅作为示例)。
在谷歌搜索这个问题后,我发现 RFC 213 which does not seem to be stable yet. However on the other hand HashMap 目前稳定版正在使用默认值,所以它应该可以工作,对吧?
对默认类型参数的支持仍然有限,但在某些情况下可以使用。当使用带有默认类型参数的struct
来指定变量的类型时,默认类型参数用于定义变量的类型:
// 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);
However on the other hand
HashMap
currently on stable is using default values, so it should be working, right?
查看HashMap
源代码,我们可以看到方法new
和with_capacity
是通过RandomState
实现的S
参数和不依赖于 HashMap
中的默认类型参数。所有其他方法都在 S
上实现为通用方法,包括其他 "constructor" 方法,如 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);