我正在尝试实现自定义集。可以毫无问题地进行编译:
var options = {mimeType: 'audio/webm;codecs=pcm'};
mediaRecorder = new MediaRecorder(stream, options);
当我尝试将单元类型(空元组)添加到struct CustomSet {}
impl CustomSet {
pub fn new() -> CustomSet {
CustomSet {}
}
}
类型时,它将无法编译。
CustomSet
以下错误
struct CustomSet<()> {}
impl CustomSet<()> {
pub fn new() -> CustomSet<()> {
CustomSet {}
}
}
如何返回具有单位数据类型的结构?我做错了什么?
答案 0 :(得分:6)
仅当CustomSet<()>
用类型参数定义时,类型CustomSet
才有意义。类型参数是变量,而不是其他类型,因此您的定义实际上没有任何意义。相反,您需要使用变量定义它:
struct CustomSet<T> {}
这意味着CustomSet
是为任何可能的类型T
定义的(要注意的是,该类型必须为Sized
,大多数类型都是如此)。
现在,上面的定义不起作用,因为Rust会抱怨您没有在类型内部使用变量T
。您不使用的变量有什么意义?
与hellow said一样,您可以使用PhantomData
,但这是您需要变量但由于某种原因实际上不需要使用变量时的一种变通方法。由于要实现集合,因此需要使用T
来将值存储在某个位置:
struct CustomSet<T> {
data: Vec<T>,
}
仍然可以针对所有可能的 T
实现这种类型的行为,而不仅仅是()
,从而使您可以重复使用许多代码:
impl<T> CustomSet<T> {
pub fn new() -> CustomSet<T> {
CustomSet {
data: Vec::new(),
}
}
}
仅当您实际使用需要完全约束T
的类型时:
let my_set: CustomSet<()> = CustomSet::new();
即使在实际程序中通常也不需要类型注释,因为可以从用法中推断出来。例如,如果您为insert
提供了一种CustomSet
方法,则可以这样使用它:
// type annotation not needed because it will be inferred from the next line
let mut my_set = CustomSet::new();
my_set.insert(());
答案 1 :(得分:4)
在这种情况下,您必须使用PhantomData
use std::marker::PhantomData;
struct CustomSet<T> {
_phantom: PhantomData<T>,
}
impl CustomSet<()> {
pub fn new() -> CustomSet<()> {
CustomSet {
_phantom: PhantomData,
}
}
}
PhantomData“通知”编译器已使用参数T
,因此不再抱怨。
请注意,尽管您在结构中添加了一个成员,但它不会再占用任何大小。
fn main() {
println!("{}", std::mem::size_of::<CustomSet<()>>()); // 0
println!("{}", std::mem::size_of::<CustomSet<u32>>()); // 0
}