我试图理解 Rust 多态性。从我的 OOP 背景来看,我希望以下 Rust 代码能够工作:
use std::io::{stdin, Read};
fn main() {
let r: Read = stdin();
println!("ok");
}
Run Code Online (Sandbox Code Playgroud)
但它没有:
use std::io::{stdin, Read};
fn main() {
let r: Read = stdin();
println!("ok");
}
Run Code Online (Sandbox Code Playgroud)
我知道有一个Readimpl for StdIn,那么我怎样才能使这个(或任何正确的方法来做到这一点)工作,即。use Stdin,或 a File,或什至是 aString如果可能(无法找到实现)在Read预期a 的地方使用?
我不认为我可以在这里使用泛型,因为我需要将 的实例(r可以是任何实现的Read)传递给另一个方法,但如果我错了,请告诉我。
您可能想在这里使用特征对象。您基本上可以通过两种方式使用特征:
fn foo<T: Trait>(x: T). 这读作“对于一个任意但固定的 T实现Trait”。fn foo(x: &Trait). 这通过使用特征对象从第一个版本中解除了“但固定”的限制。如果您想要一个变量,该变量可以保存对Stdin或 aFile或任何其他实现的引用Read,则不能采用静态调度解决方案,因为您的实现类型不是固定的。
那么你的变量的类型是什么?Read? 可悲的是,这并不容易。性状对象是未上浆的,并且不能在堆栈上直接使用。相反,你只能与交互特征通过引用/指针,就像对象&Read,&mut Read,Box<Read>等等。现在我们使用了借用东西,我们可能会遇到更多与此相关的问题。幸运的是,您并不是第一个遇到此问题的人:请参阅此问题此特定用例的详细信息,。
为了简化一点,在大多数情况下可以使用Box<Trait>. 在您的情况下,它看起来像这样:
use std::io::{stdin, Read};
fn main() {
let r: Box<Read> = Box::new(stdin());
println!("ok");
}
Run Code Online (Sandbox Code Playgroud)