繁体   English   中英

将通用参数转换为特定类型

[英]Cast a generic param to a specific type

如果我有两个结构:

struct A {...}
struct B {...}

和一个通用函数fn f<T>(param: T) ,我通过传递对AB的引用调用它,在该函数中有没有办法拥有这样的东西(伪代码):

if param is A {
    // do something with "param as A", like this:
    let a: A = (A) param;
    // ...
}

在 Java、C# 等语言中,我会简单地检查一个对象是否是A的实例,如果是,则将其强制转换为A如上例所示。 我怎样才能在 Rust 中做这样的事情? 我知道我可以在 trait 中加入一些特定于类型的逻辑,但我特别要求一种更简单、更直接的方法。

您可以使用Any trait 的 trait 对象来完成您所要求的操作,例如

use std::any::Any;

#[derive(Debug)]
struct A;
#[derive(Debug)]
struct B;

fn foo(param: &dyn Any) {
    if let Some(a) = param.downcast_ref::<A>() {
        dbg!(a);
    }
    if let Some(b) = param.downcast_ref::<B>() {
        dbg!(b);
    }
}

但是,对于常见的用例,有更多地道、符合人体工程学和高效的解决方案。 您在问题中提到在AB上实现一个共同特征,这是一种方法。 另一种方法是为您要支持的所有类型定义一个带有变体的枚举:

enum MyEnum {
    A(A),
    B(B),
}

fn bar(param: MyEnum) {
    match param {
        MyEnum::A(a) => { dbg!(a); },
        MyEnum::B(b) => { dbg!(b); },
    }
}

你正在寻找的东西在当前的 Rust 中还没有完全可用,但一旦专业化功能登陆就会可用。 使用专业化并在当前每晚可测试,您的函数将如下所示:

#![feature(min_specialization)]

struct A {}
struct B {}

fn f<T>(param: Vec<T>) {
    trait Detect {
        fn detect(&self);
    }
    impl<T> Detect for Vec<T> {
        default fn detect(&self) {
            println!("I am something else");
        }
    }
    impl Detect for Vec<A> {
        fn detect(&self) {
            println!("I am a Vec<A>");
        }
    }
    param.detect();
    // ...
}

fn main() {
    f(Vec::<A>::new());
    f(Vec::<B>::new());
}

操场

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM