具有通用特征的结构,其也是通用特征

时间:2017-02-07 15:54:44

标签: rust traits

在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结构?

2 个答案:

答案 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,因此灵活性稍差一些,但根据您的需要,这可能就足够了。