【问题标题】:Struct with a generic trait which is also a generic trait具有通用特征的结构,这也是通用特征
【发布时间】:2017-06-24 23:00:56
【问题描述】:

在 Rust 1.15 中,我创建了一个 trait 来抽象读取和解析文件格式。我正在尝试创建一个内部具有此通用特征的结构。

我有这个特点:

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&lt;R: Read&gt;+'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 结构?

【问题讨论】:

  • 好吧,我很抱歉。推送评论后立即注意到。 :x 你有没有听从PhantomData 的建议?
  • @E_net4 我不太确定该怎么做?

标签: rust traits


【解决方案1】:

错误消息建议您使用标记,例如PhantomData。你可以这样做:

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,
}

这有点不太灵活,因为每个MyReader 的实现只能选择一个Source,但它可能就足够了,这取决于您的需要。

【讨论】:

    【解决方案2】:

    你可能不想要类型参数,你想要一个关联类型

    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() {}
    

    另见:

    【讨论】:

    • 谢谢 - 那里有一些有见地的链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 2017-01-04
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    相关资源
    最近更新 更多