注意:今天早些時候我問了一個類似的問題,但這個問題有很大的不同,所以我把它作為一個單獨的問題發布。
如果我有兩個(或更多)結構:
struct A {...}
struct B {...}
以及fn f<T>(param: Vec<T>)我通過傳遞Aor B(或其他型別的向量)呼叫的通用函式,該函式中是否有辦法擁有這樣的東西(偽代碼):
if param is Vec<A> {
// do something with "param as Vec<A>", like this:
let a: Vec<A> = (Vec<A>) param;
// ...
}
通常在 OOP 語言中,我基本上可以檢查向量引數的型別或其元素之一(假設向量不為空)并轉換引數。
在 Rust 中,是否有一種簡單而直接的方法來實作這一點,而無需犧牲性能,也無需更改函式簽名或在函式外撰寫任何代碼(因此沒有列舉包裝器、特征、動態/運行時“魔術” “, 等等。)。
uj5u.com熱心網友回復:
你正在尋找的東西在當前的 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());
}
操場
它甚至可以通過提供一個類似“cast”的特性來變得通用:
trait Cast<To> {
fn with_cast(&self, fun: impl FnOnce(Option<&To>));
}
impl<T, To> Cast<To> for T {
default fn with_cast(&self, fun: impl FnOnce(Option<&To>)) {
fun(None)
}
}
使用Cast,該f函式將如下所示:
fn f<T>(param: Vec<T>) {
impl Cast<Vec<A>> for Vec<A> {
fn with_cast(&self, fun: impl FnOnce(Option<&Self>)) {
fun(Some(self));
}
}
param.with_cast(|val: Option<&Vec<A>>| {
if let Some(_param_a) = val {
// here I can access fields of param_a
println!("I'm a Vec<A>");
} else {
println!("I'm something else");
}
});
// ...
}
操場
uj5u.com熱心網友回復:
Any如果您能夠約束,您仍然可以使用鏈接問題中所示的方法T: 'static
use std::any::Any;
struct A {}
struct B {}
fn f<T: 'static>(param: Vec<T>) {
if let Some(_param_a) = (¶m as &dyn Any).downcast_ref::<Vec<A>>() {
println!("I am a Vec<A>");
}
else {
println!("I am something else");
}
}
fn main() {
f(Vec::<A>::new());
f(Vec::<B>::new());
}
這沒有任何運行時成本。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/339400.html
