我试图匹配 struct 的泛型字段的数据类型,并做出相应的react .我的总体 idea 是这样的(代码不编译):

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美元来匹配第一个.实际上我不确定我想做什么可以做到,但什么能达到预期的效果呢?

推荐答案

Idiomatic Solution

创建一个限制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();
}

这是principled个泛型编程,您可以在其中准确地声明可能的泛型参数的行为差异,这样就不会有什么意外了.

另见:


Exact Solution

Rust确实可以查询类型:每个类型都有一个唯一的TypeId个关联,您可以在TypeId上匹配一系列的if个判断.它很笨重.

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

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

Rust相关问答推荐

交叉术语未正确清除屏幕

抽象RUST中的可变/不可变引用

两个相关特征的冲突实现错误

在UdpSocket上使用sendto时的隐式套接字绑定

你是如何在铁 rust 一侧的金牛座获得应用程序版本的?

自定义结果枚举如何支持`?`/`FromResidual`?

Gtk4-rs:将监视器作为gdk::monitor获取,而不是作为glib::对象获取

Pin<;&;mut可能将Uninit<;T>;>;合并为Pin<;&;mut T>;

将serde_json读入`VEC<;T&>;`( rust 色)时出现问题

循环访问枚举中的不同集合

对于rustc编译的RISC-V32IM二进制文件,llvm objdump没有输出

为什么 Rust 创建的 f32 小于 f32::MIN_POSITIVE?

在 Rust 中,在第一个空格上分割字符串一次

在描述棋盘时如何最好地使用特征与枚举

为什么我的trait 对象类型不匹配?

在发布中包含 Rust DLL

如何限制通用 const 参数中允许的值?

如何在 Rust 中将 UTF-8 十六进制值转换为 char?

改变不实现克隆的 dioxus UseState struct

如何解析 Rust 中的 yaml 条件字段?