Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
137 views
in Technique[技术] by (71.8m points)

No trait inferred from structs that implement a trait in Rust?

I have 2 structs, both implement a trait:

pub trait TFilter {
    fn getText(&self) -> String;
}

pub struct CommentFilter {
    comment: String
}

impl TFilter for CommentFilter {
    fn getText(&self) -> String {
        return self.comment;
    }
}

impl CommentFilter {
    pub fn from_text(context: &Context, text: String) -> Self {
        return CommentFilter {
            comment: text
        }
    }
}

// ---

pub struct RegExpFilter {
    text: String
}

impl RegExpFilter {
    pub fn from_text(context: &Context, text: String) -> Self {
        return RegExpFilter {
            text
        }
    }
}

impl TFilter for RegExpFilter {
    fn getText(&self) -> String {
        return self.text
    }
}



But when trying to compile the code:

      let filter: dyn TFilter = if text.chars().nth(0).unwrap() == '!' {
                CommentFilter::from_text(context, text);
            } else {
                RegExpFilter::from_text(context, "test".to_string());
            };

i get an error:

error[E0308]: mismatched types
   --> src/filter.rs:113:20
    |
113 |               } else {
    |  ____________________^
114 | |                 RegExpFilter::from_text(context, "test".to_string());
115 | |             };
    | |_____________^ expected trait object `dyn filter::TFilter`, found `()`

What's wrong?

PS1. I found ; actually hurt, but now i'm getting:

expected trait object dyn filter::TFilter, found struct filter::CommentFilter

Can't it detect they actually implement the trait?

PS2. I had to explicitly specify : dyn TFilter as otherwise the compiler infers it from the first if branch and detected as CommentFilter (which obviously does not work for the negative branch).

question from:https://stackoverflow.com/questions/65884753/no-trait-inferred-from-structs-that-implement-a-trait-in-rust

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Since the compiler does not know the size of TFilter you need to store it on the heap wrapped in a Box like this:

      let filter: Box<dyn TFilter> = if text.chars().nth(0).unwrap() == '!' {
            Box::new(CommentFilter::from_text(context, text))
        } else {
            Box::new(RegExpFilter::from_text(context, "test".to_string()))
        };

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...