[英]Cast a generic param to a specific type
如果我有兩個結構:
struct A {...}
struct B {...}
和一個通用函數fn f<T>(param: T)
,我通過傳遞對A
或B
的引用調用它,在該函數中有沒有辦法擁有這樣的東西(偽代碼):
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);
}
}
但是,對於常見的用例,有更多地道、符合人體工程學和高效的解決方案。 您在問題中提到在A
和B
上實現一個共同特征,這是一種方法。 另一種方法是為您要支持的所有類型定義一個帶有變體的枚舉:
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.