rust - 对于实现相同特征的结构,如何克服具有不兼容类型的匹配臂?

标签 rust

我正在尝试编写 cat 命令来学习 Rust,但我似乎无法将命令行参数转换为读取器结构。

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(),
  |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^

似乎不可能以多态方式匹配特征实现者 (related) .我如何使用 FileStdin 作为阅读器?

最佳答案

问题是 stdin() 返回类型为 StdioFile::open(...).unwrap() 返回类型为 File 的对象。在 Rust 中,匹配的所有分支都必须返回相同类型的值。

在这种情况下,您可能希望返回一个通用的 Read 对象。不幸的是 Read 是一个特征,所以你不能按值传递它。最简单的替代方法是求助于堆分配:

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>,
        };
    }
}

关于rust - 对于实现相同特征的结构,如何克服具有不兼容类型的匹配臂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26378842/

相关文章:

rust - 如何使用 serde_json 动态构建 json 数组或对象?

rust - 在当前范围内找不到类型 `subtractPointFromPoint` 的名为 `()` 的方法

vector - 如何获取和替换 Rust Vec 中的值?

types - 为什么由于缺少类型注释而收到错误 "trait bound FromStr is not satisfied"?

rust - 取消引用 *mut T 转换为 *mut ManuallyDrop<T> 是未定义的行为吗?

rust - Rust 中无限循环的可用性

hashmap - 如何创建值可以是多种类型之一的 Rust HashMap?

rust - 作为返回 traitobject 的 Supertrait 在编译时没有已知的大小

winapi - 为什么在将 EvtQuery 与 winapi crate 一起使用时会出现 ERROR_INVALID_PARAMETER?

python - Rust vs python 程序性能结果问题