Why can't a struct be assigned to a binding with a trait it implements

rust

Solution

You probably want to use trait objects here. You can use traits in basically two ways:

- The static dispatch way: `fn foo<T: Trait>(x: T)`. This reads "for an arbitrary, but fixed `T` which implements `Trait`".

- The dynamic dispatch way: `fn foo(x: &Trait)`. This lifts the "but fixed" limitation from the first version by using trait objects.

If you want to have a variable which could either hold a reference to `Stdin` or a `File` or anything else that implements `Read`, you can't go for the static dispatch solution, as your implementing type is not fixed.

So what is the type of your variable then? `Read`? Sadly, it's not that easy. Trait objects are unsized and can't be used on the stack directly. Instead you can only interact with trait objects via references/pointers, like `&Read`, `&mut Read`, `Box<Read>` and so on. Now that we use borrowing-stuff, we might encounter more problems related to that. Luckily, you haven't been the first one encountering this issue: see this question for a detailed look at this specific use case.

To simplify a bit, in most cases it's ok to use `Box<Trait>`. In your case, it would look like this:

use std::io::{stdin, Read};

fn main() {
    let r: Box<Read> = Box::new(stdin());
    println!("ok");
}

Problem

I am trying to understand Rust polymorphism. From my background in OOP, I would expect the following Rust code to work: ``` use std::io::{stdin, Read}; fn main() { let r: Read = stdin(); println!("ok"); } ``` But it doesn't: ``` 4 | let r: Read = stdin(); | ^^^^^^^ expected trait std::io::Read, found struct `std::io::Stdin` ``` I know that there's a `Read` impl for `StdIn`, so how can I make this (or whatever is the correct way to do this) work, ie. use `Stdin`, or a `File`, or even a `String` if possible (couldn't find a implementation for that) be used where a `Read` is expected? I don't think I can use generics here as I need to pass an instance of `r`, which can be whatever that implements `Read`, to another method later, but please tell me if I am wrong.

Original source

Related problems