问题描述
我正在尝试编写 cat
命令来学习 Rust,但我似乎无法将命令行参数转换为读取器结构.
I am attempting to write the cat
command to learn Rust, but I can't seem to convert command line arguments into reader structs.
use std::{env, io};
use std::fs::File;
fn main() {
for arg in env::args().skip(1) {
let reader = match arg.as_str() {
"-" => io::stdin(),
path => File::open(&path).unwrap(),
};
}
}
错误:
error[E0308]: match arms have incompatible types
--> src/main.rs:6:22
|
6 | let reader = match arg.as_str() {
| ^ expected struct `std::io::Stdin`, found struct `std::fs::File`
|
= note: expected type `std::io::Stdin`
= note: found type `std::fs::File`
note: match arm with an incompatible type
--> src/main.rs:8:21
|
8 | path => File::open(&path).unwrap(),
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
似乎不可能多态匹配特征实现者(相关).如何使用 File
或 Stdin
作为阅读器?
It doesn't seem like it's possible to polymorphically match trait implementers (related). How can I use either a File
or Stdin
as a reader?
推荐答案
问题在于 stdin()
返回一个类型为 Stdio
和 File 的对象::open(...).unwrap()
返回一个 File
类型的对象.在 Rust 中,匹配的所有分支都必须返回相同类型的值.
The problem is that stdin()
returns an object of type Stdio
and File::open(...).unwrap()
returns an object of type File
. In Rust, all arms of a match have to return values of the same type.
在这种情况下,您可能想要返回一个通用的 Read
对象.不幸的是 Read
是一个 trait,所以你不能按值传递它.最简单的替代方法是使用堆分配:
In this case you probably wanted to return a common Read
object. Unfortunately Read
is a trait so you cannot pass it by value. The easiest alternative is to resort to heap allocation:
use std::{env, io};
use std::io::prelude::*;
use std::fs::File;
fn main() {
for arg in env::args().skip(1) {
let reader = match arg.as_str() {
"-" => Box::new(io::stdin()) as Box<Read>,
path => Box::new(File::open(&path).unwrap()) as Box<Read>,
};
}
}
这篇关于对于实现相同特征的结构,如何克服具有不兼容类型的匹配臂?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!