簡體   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