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

Posted

技术标签:

【中文标题】具有通用特征的结构,这也是通用特征【英文标题】: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 我不太确定该怎么做? ***.com/a/40487993/1233251 【参考方案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() 

另见:

When is it appropriate to use an associated type versus a generic type? Why am I getting "parameter is never used [E0392]"? How can I have an unused type parameter in a struct?

【讨论】:

谢谢 - 那里有一些有见地的链接。

以上是关于具有通用特征的结构,这也是通用特征的主要内容,如果未能解决你的问题,请参考以下文章

angular 1.x 是不是具有通用特征或模式?

Rust 无法推断通用特征 impl 的返回类型

Groupby 在一列 pandas 数据帧上,并使用 GridsearchCv 使用通用 sklearn 管道训练每个组的特征和目标 (X, y)

当后者具有隐式参数时,如何正确地将特征绑定到其 impl

PHP 特征 - 定义通用常量

无法在锈柴油中使用通用参数实现特征