返回并使用具有匹配项的泛型类型

异氰酸烯丙酯

我正在开发一个简单的Rust应用程序,该应用程序可以接受stdin并根据它进行操作。我想让每个命令返回一个结果向量。

不同的命令可能返回不同类型的向量。list方法返回PathBufs的向量,但默认的match臂返回字符串:

use std::{io, fs};
use std::path::PathBuf;

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input).expect("Failed to read line");
    let chars_to_trim: &[char] = &['\n'];
    let trimmed_input: &str = input.trim_matches(chars_to_trim);

    let no_match = vec!["No Match"];

    let result = match trimmed_input {
        "list" => list(),
        _ => no_match,
    };
}

fn list() -> Vec<PathBuf> {
    println!("{}", "list of lockfiles here");
    let entries = fs::read_dir("/tmp").expect("Failed to read /tmp");
    let all: Result<_, _> = entries.map(|entry| entry.map(|e| e.path())).collect();
    all.expect("Unable to read an entry")
}

这将导致编译失败:

error[E0308]: match arms have incompatible types
  --> src/main.rs:12:22
   |
12 |         let result = match trimmed_input {
   |                      ^ expected struct `std::path::PathBuf`, found &str
   |
   = note: expected type `std::vec::Vec<std::path::PathBuf>`
   = note:    found type `std::vec::Vec<&str>`
note: match arm with an incompatible type
  --> src/main.rs:14:18
   |
14 |             _ => no_match,
   |                  ^^^^^^^^

Rust的惯用方式是什么?我已经阅读了有关泛型的文档,但不确定如何应用。

Shepmaster

这是一个简化的测试用例:

use std::path::PathBuf;

fn main() {
    let paths: Vec<PathBuf> = Vec::new();
    let defaults: Vec<&'static str> = Vec::new();

    let result = match 1 {
        1 => paths,
        _ => defaults,
    };
}

正如错误消息试图说的那样,Rust要求单个变量始终具有相同的类型。让一个变量成为集合中的未知类型根本没有意义。

您可以做的最直接的事情是创建一个enum包装您拥有的两种情况的包装:

use std::path::PathBuf;

enum MyThing<'a> {
    Str(&'a str),
    Path(PathBuf),
}

fn main() {
    let paths: Vec<PathBuf> = Vec::new();
    let defaults: Vec<&'static str> = Vec::new();

    let result: Vec<_> = match 1 {
        1 => paths.into_iter().map(MyThing::Path).collect(),
        _ => defaults.into_iter().map(MyThing::Str).collect(),
    };
}

您也可以选择一个中间立场并转换为该类型,也许String

use std::path::PathBuf;

fn main() {
    let paths: Vec<PathBuf> = Vec::new();
    let defaults: Vec<&'static str> = Vec::new();

    let result: Vec<_> = match 1 {
        1 => paths.into_iter().map(|p| p.to_string_lossy().into_owned()).collect(),
        _ => defaults.into_iter().map(|s| s.to_string()).collect(),
    };
}

第三种选择是创建一个特征并为两种类型实现。然后,您可以创建一个特征对象此选项最接近您可能熟悉的动态语言。它增加了一个间接层,从而提供了更大的灵活性:

use std::path::PathBuf;

trait MyTrait {
    fn size(&self) -> u8;
}

impl MyTrait for PathBuf {
    fn size(&self) -> u8 {
        15
    }
}

impl<'a> MyTrait for &'a str {
    fn size(&self) -> u8 {
        88
    }
}

fn main() {
    let paths: Vec<PathBuf> = Vec::new();
    let defaults: Vec<&'static str> = Vec::new();

    let result: Vec<_> = match 1 {
        1 => paths.into_iter().map(|p| Box::new(p) as Box<MyTrait>).collect(),
        _ => defaults.into_iter().map(|s| Box::new(s) as Box<MyTrait>).collect(),
    };
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在Scala中使用具有泛型类型的lambda

来自分类Dev

在Where Linq语句中使用具有泛型类型的==运算符

来自分类Dev

在 C# 中,如何使用具有两种不同类型的泛型?

来自分类Dev

如何在 useReducer 中使用具有必填字段的泛型类型?

来自分类Dev

调用具有多个泛型类型的泛型方法,而无需指定每个泛型类型

来自分类Dev

如何实现工厂特征返回具有匹配类型参数的泛型值?

来自分类Dev

具有泛型返回类型的vararg方法中的@SafeVarargs

来自分类Dev

如何继承具有不同泛型返回类型的方法

来自分类Dev

Kotlin - 具有泛型返回类型的抽象函数

来自分类Dev

具有泛型类型的函数中使用的Ordeby(),Where()等

来自分类Dev

在C#中使用具有“递归”关系的泛型

来自分类Dev

Swift:使用具有命名空间的泛型方法扩展数组

来自分类Dev

使用反射調用具有約束的泛型方法

来自分类Dev

如何在Swift中从带有类型别名的协议中引用具有约束的泛型类?

来自分类Dev

如何使用已知类型作为参数创建具有泛型的泛型类?

来自分类Dev

在Java中,是否可以使用具有两个类型参数的泛型接口作为每个具有一个固定类型参数的子类型接口的基础?

来自分类Dev

具有泛型类型的泛型集合生成

来自分类Dev

具有泛型类型的泛型集合生成

来自分类Dev

具有多个特征的泛型类型

来自分类Dev

创建具有泛型类型的函数

来自分类Dev

具有泛型的Scala类型类

来自分类Dev

具有多个泛型类型的ArrayList?

来自分类Dev

具有接口类类型的泛型

来自分类Dev

具有泛型类型的contains()

来自分类Dev

具有泛型类型的属性

来自分类Dev

注入具有具体类型的泛型接口是否违反了依赖项注入的目的?

来自分类Dev

如何从具有泛型返回类型和 where 子句的方法返回值

来自分类Dev

如何使用具有不同父项的CSS选择器获取最后匹配的元素?

来自分类Dev

如何使用泛型返回泛型类的类类型?

Related 相关文章

  1. 1

    在Scala中使用具有泛型类型的lambda

  2. 2

    在Where Linq语句中使用具有泛型类型的==运算符

  3. 3

    在 C# 中,如何使用具有两种不同类型的泛型?

  4. 4

    如何在 useReducer 中使用具有必填字段的泛型类型?

  5. 5

    调用具有多个泛型类型的泛型方法,而无需指定每个泛型类型

  6. 6

    如何实现工厂特征返回具有匹配类型参数的泛型值?

  7. 7

    具有泛型返回类型的vararg方法中的@SafeVarargs

  8. 8

    如何继承具有不同泛型返回类型的方法

  9. 9

    Kotlin - 具有泛型返回类型的抽象函数

  10. 10

    具有泛型类型的函数中使用的Ordeby(),Where()等

  11. 11

    在C#中使用具有“递归”关系的泛型

  12. 12

    Swift:使用具有命名空间的泛型方法扩展数组

  13. 13

    使用反射調用具有約束的泛型方法

  14. 14

    如何在Swift中从带有类型别名的协议中引用具有约束的泛型类?

  15. 15

    如何使用已知类型作为参数创建具有泛型的泛型类?

  16. 16

    在Java中,是否可以使用具有两个类型参数的泛型接口作为每个具有一个固定类型参数的子类型接口的基础?

  17. 17

    具有泛型类型的泛型集合生成

  18. 18

    具有泛型类型的泛型集合生成

  19. 19

    具有多个特征的泛型类型

  20. 20

    创建具有泛型类型的函数

  21. 21

    具有泛型的Scala类型类

  22. 22

    具有多个泛型类型的ArrayList?

  23. 23

    具有接口类类型的泛型

  24. 24

    具有泛型类型的contains()

  25. 25

    具有泛型类型的属性

  26. 26

    注入具有具体类型的泛型接口是否违反了依赖项注入的目的?

  27. 27

    如何从具有泛型返回类型和 where 子句的方法返回值

  28. 28

    如何使用具有不同父项的CSS选择器获取最后匹配的元素?

  29. 29

    如何使用泛型返回泛型类的类类型?

热门标签

归档