rust - 如何匹配 Rust 中的数据类型?

标签 rust

我正在尝试匹配结构的通用字段的数据类型并做出相应的 react 。我的总体想法是这样的(代码无法编译):

struct Foo<T> {
    bar: T,
}

fn main() {
    let x = Foo::<String> {
        bar: "world".to_string(),
    };

    match x.bar {
        String => println!("It's a string!"),
        u32 => println!("It's a u32!"),
        _ => println!("Something else"),
    };

    println!("end of program!");
}

编译器的错误信息:

warning: unreachable pattern
  --> src/main.rs:12:9
   |
11 |         String => println!("It's a string!"),
   |         ------ matches any value
12 |         u32 => println!("It's a u32!"),
   |         ^^^ unreachable pattern
   |
   = note: `#[warn(unreachable_patterns)]` on by default

warning: unreachable pattern
  --> src/main.rs:13:9
   |
11 |         String => println!("It's a string!"),
   |         ------ matches any value
12 |         u32 => println!("It's a u32!"),
13 |         _ => println!("Something else"),
   |         ^ unreachable pattern

warning: unused variable: `String`
  --> src/main.rs:11:9
   |
11 |         String => println!("It's a string!"),
   |         ^^^^^^ help: consider prefixing with an underscore: `_String`
   |
   = note: `#[warn(unused_variables)]` on by default

warning: unused variable: `u32`
  --> src/main.rs:12:9
   |
12 |         u32 => println!("It's a u32!"),
   |         ^^^ help: consider prefixing with an underscore: `_u32`

warning: variable `String` should have a snake case name
  --> src/main.rs:11:9
   |
11 |         String => println!("It's a string!"),
   |         ^^^^^^ help: convert the identifier to snake case: `string`
   |
   = note: `#[warn(non_snake_case)]` on by default

我想要的是 x 匹配第一个。我其实并不确定我想做的事能不能做,但怎样才能达到预期的效果呢?

最佳答案

惯用的解决方案

Foo 中创建一个约束参数 T 的特征,将任何特定行为实现为该特征的关联函数。

例子:

trait PrintMe {
    fn print_me(&self);
}

impl PrintMe for String {
    fn print_me(&self) { println!("I am a string"); }
}

struct Foo<T: PrintMe> {
    bar: T
}

fn main() {
    // ...
    x.bar.print_me();
}

这是有原则的泛型编程,您可以在其中准确声明可能的泛型参数的行为差异,因此不会出现意外。

另见:


精确解

Rust 确实可以查询类型:每种类型都有一个唯一的 TypeId关联,您可以通过一系列 if 检查来匹配 TypeId。它很笨重。

fn print_me<T>(x: &Foo<T>) {
    if TypeId::of::<T>() == TypeId::of::<String>() {
        println!("I am a string");
    } else // ...
}

但是请...不要那样做:)

关于rust - 如何匹配 Rust 中的数据类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41596628/

相关文章:

rust - 我是否必须 'use' 一个特征才能调用该特征中定义的方法?

rust - 读取和写入长时间运行的 std::process::Child

rust - 当返回对范围外值的可变引用的不可变引用时,为什么在范围结束时丢弃可变引用?

高阶函数中的 Rust 生命周期

rust - 移入和移出可变借用结构

rust - 所有 Rust 属性都是宏吗?

rust - 为什么 Rust 不能在简单的闭包中推断出正确的生命周期,或者推断出它们是冲突的?

javascript - 从 React 应用程序向 Rocket 后端发送 POST 请求时出错

generics - 如何在泛型函数中请求和使用结构(没有结构实例!)?

recursion - 在递归枚举上使用附带移动值错误