Generics 如何使用闭包抽象数据和操作

Generics 如何使用闭包抽象数据和操作,generics,rust,Generics,Rust,我正在尝试创建代码,从某个源双向读取数据,而无需代码重复 使用std::iter; 结构读取器{ 资料来源:Vec, 数据修订版:Vec, 数据框, 数据_it_版本:框, } 枚举方向{向前,向后} impl阅读器{ fn读取(&M-self,n:usize,direction:direction){ 让(它,加法器)=匹配方向{ 方向::前进=>{ 让加法器:Box()>=Box::new(| idx | self.data.push(idx)); (&self.data_it,加法器) }

我正在尝试创建代码,从某个源双向读取数据,而无需代码重复

使用std::iter;
结构读取器{
资料来源:Vec,
数据修订版:Vec,
数据框,
数据_it_版本:框,
}
枚举方向{向前,向后}
impl阅读器{
fn读取(&M-self,n:usize,direction:direction){
让(它,加法器)=匹配方向{
方向::前进=>{
让加法器:Box()>=Box::new(| idx | self.data.push(idx));
(&self.data_it,加法器)
}
方向::向后=>{
让加法器:Box()>=Box::new(|idx | self.data_rev.insert(0,idx));
(&self.data\u it\u rev,加法器)
}
};
对于其中的idx.by_ref().take(n){
加法器(idx);
}
}
}
完整代码是

在本例中,我试图表示的是
read
函数,它具有公共代码和一些代码,这些代码随
read
应该发生的方向而变化。 很明显,如何使用方向上的多个模式匹配来编写此代码,但我不想重复自己的操作

如果可能的话,我想让方向成为某种通用参数,并有类似的东西

结构读取器{ 资料来源:Vec, 数据框 } 特质读取器{ fn读取(&mut self) } //代码中的某个地方 让读取器=匹配方向{ 方向::前进=>self.Forward\u读取器; 方向::后退=>self.Backward\u读取器; } reader.read()
请注意,将方向放在通用参数中,就像放在最终代码中一样,意味着方向是静态地为
读取器的每个实例确定的,并且不能更改。如果这是您想要的,您可以通过将
方向
作为一个特征,将
向前
向后
作为实现该特征的类型来实现:

trait Direction{}
struct Forward{}
impl Direction for Forward {}
struct Backward{}
impl Direction for Backward {}

struct Reader<D: Direction> {
    data: Vec<usize>,
    data_it: Box<dyn Iterator<Item = usize>>,
    direction: D,
}

impl Reader<Forward> {
    fn read (&mut self) { unimplemented!(); }
}

impl Reader<Backward> {
    fn read (&mut self) { unimplemented!(); }
}

由于您希望能够拥有每个特性的实例并在运行时在它们之间切换,因此需要在特性中定义接口,然后使用对该特性的引用。此外,为了能够从trait实现访问公共函数,还需要在super-trait中定义它们:

pub trait Direction{}
pub struct Forward{}
impl Direction for Forward {}
pub struct Backward{}
impl Direction for Backward {}

pub trait CommonReader {
    fn common_function (&self);
}

pub trait ReaderItf: CommonReader {
    fn read (&mut self);
}

pub struct Reader<D: Direction> {
    pub data: Vec<usize>,
    pub data_it: Box<dyn Iterator<Item = usize>>,
    pub direction: D,
}

impl ReaderItf for Reader<Forward> {
    fn read (&mut self) { self.common_function(); }
}

impl ReaderItf for Reader<Backward> {
    fn read (&mut self) { unimplemented!(); }
}

impl<T: Direction> CommonReader for Reader<T> {
    fn common_function (&self) { unimplemented!(); }
}

// And you use it like this wherever you want to switch at runtime:
pub fn use_reader (r: &mut dyn ReaderItf) {
    r.read();
}
pub trait Direction{}
发布结构转发{}
正向{}的impl方向
发布结构向后{}
向后{}的impl方向
公共读物{
fn公共_函数(和自身);
}
pub-trait-readerif:CommonReader{
fn读取(&mut-self);
}
发布结构读取器{
发布数据:Vec,
pub data_it:Box,
酒吧方向:D,
}
读卡器的impl readerif{
fn read(&mut self){self.common_function();}
}
读卡器的impl readerif{
fn读取(&mut self){未实现!();}
}
为读者导入CommonReader{
fn公共_函数(&self){未实现!();}
}
//在运行时,无论您想在何处切换,都可以这样使用它:
发布fn使用\u读取器(r:&mut dyn READERTIF){
r、 read();
}

我想这个问题的答案是。在闭包中使用
self.data
时,闭包将借用所有
self
;您可以通过创建一个只借用
self.data
的变量,并在闭包中使用它来绕过它。您的代码还引发了一些其他错误,但它们都是相当简单的可变性问题。我不太确定泛型版本要到哪里去,所以我不能对这部分进行评论。@trentcl,因为如果省略
方向
字段,编译器会建议这样做。但是你是对的,它可以是直接的
D
,我现在就修改它。应该总是有两个读卡器——一个向前,一个向后,一个给我,所以它们是静态的。我不确定的是如何在运行时更改它们?通过使用装箱引用?当尝试从读取中使用公共函数时,我得到错误
找不到公共函数
读取中访问
公共函数
在。@user1685095如果将不同的行为推入
impl
块,您可以取消类型参数的大小并使用
读取器
;这对你有帮助吗?
pub trait Direction{}
pub struct Forward{}
impl Direction for Forward {}
pub struct Backward{}
impl Direction for Backward {}

pub trait CommonReader {
    fn common_function (&self);
}

pub trait ReaderItf: CommonReader {
    fn read (&mut self);
}

pub struct Reader<D: Direction> {
    pub data: Vec<usize>,
    pub data_it: Box<dyn Iterator<Item = usize>>,
    pub direction: D,
}

impl ReaderItf for Reader<Forward> {
    fn read (&mut self) { self.common_function(); }
}

impl ReaderItf for Reader<Backward> {
    fn read (&mut self) { unimplemented!(); }
}

impl<T: Direction> CommonReader for Reader<T> {
    fn common_function (&self) { unimplemented!(); }
}

// And you use it like this wherever you want to switch at runtime:
pub fn use_reader (r: &mut dyn ReaderItf) {
    r.read();
}