在Rust 1.15中,我创造了一个特征来抽象阅读&解析文件格式。我试图创建一个内部具有此通用特征的结构。
我有这个特点:
use std::io::Read;
trait MyReader<R: Read> {
fn new(R) -> Self;
fn into_inner(self) -> R;
fn get_next(&mut self) -> Option<u32>;
fn do_thingie(&mut self);
}
我想创建一个结构,它引用了实现它的东西。
struct MyIterThing<'a, T: MyReader<R>+'a> {
inner: &'a mut T,
}
给出以下错误:
error[E0412]: type name `R` is undefined or not in scope
--> <anon>:11:36
|
11 | struct MyIterThing<'a, T: MyReader<R>+'a> {
| ^ undefined or not in scope
|
= help: no candidates by the name of `R` found in your project; maybe you misspelled the name or forgot to import an external crate?
T: MyReader+'a
,我收到错误:"error[E0243]: wrong number of type arguments: expected 1, found 0"
,T: MyReader<R: Read>+'a
提供了一个低级语法错误,它没有预期:
那里。
这也不起作用:
error[E0392]: parameter `R` is never used
--> <anon>:11:24
|
11 | struct MyIterThing<'a, R: Read, T: MyReader<R>+'a> {
| ^ unused type parameter
|
= help: consider removing `R` or using a marker such as `std::marker::PhantomData`
如何创建MyIterThing
结构?
答案 0 :(得分:4)
您可能不需要类型参数,您需要关联类型:
use std::io::Read;
trait MyReader {
type R: Read;
fn new(Self::R) -> Self;
fn into_inner(self) -> Self::R;
fn get_next(&mut self) -> Option<u32>;
fn do_thingie(&mut self);
}
struct MyIterThing<'a, T>
where T: MyReader + 'a
{
inner: &'a mut T,
}
fn main() {}
另见:
答案 1 :(得分:2)
错误消息为您提供了使用标记的建议,例如PhantomData。你可以这样做:
map.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
@Override
public void onInfoWindowClick(Marker marker) {
String title = marker.getTitle(); // Retrieve the title
}
});
use std::marker::PhantomData;
struct MyIterThing<'a, R: Read, T: MyReader<R> + 'a> {
inner: &'a mut T,
marker: PhantomData<R>,
}
的实例的运行时成本为零,因此使用该实例比仅创建PhantomData
类型的字段更好。
另一种解决方案是使用关联类型而不是类型参数:
R
由于trait MyReader {
type Source: Read;
fn new(Self::Source) -> Self;
fn into_inner(self) -> Self::Source;
fn get_next(&mut self) -> Option<u32>;
fn do_thingie(&mut self);
}
struct MyIterThing<'a, T: MyReader + 'a> {
inner: &'a mut T,
}
的每个实施只能选择Source
,因此灵活性稍差一些,但根据您的需要,这可能就足够了。