就我的理解而言,泛型允許在不同型別之間共享相同的行為。為實體,
trait Bird {}
struct BirdFly {}
impl Bird for BirdFly {
pub fn fly() -> can fly
}
struct BirdCanntFly {}
impl Bird for BirdCanntFly{
pub fn fly() -> cannt fly
}
let birds = vec![
Box::new(BirdFly{}), // allow this bird to fly, for instance
Box::new(BirdCanntFly{}), // dont't allow this bird to fly
];
我的問題是相反的,即是否有可能讓相同的型別采取不同的行為(沒有 ifs、enums 或 Box)。在這個例子中,在兩種型別(BirdFly 和 BirdCanntFly)維度相同,只是行為不同。就像是:
struct Bird {
fly: // associate different behavior
}
let birds = vec![
Bird{ fly: some_fly_behavior }, // allow this bird to fly, for instance
Bird{ fly: another_fly_behavior }, // dont't allow this bird to fly
];
birds[0].fly();
birds[1].fly();
如果 fly 收到相同的引數并回傳相同的型別,我看不出問題的原因。此外,通過這種方式,我可以擺脫矢量內的 Box。特別是因為我可能在向量中有數百萬個元素并且被多次迭代訪問,這樣我就可以避免開銷。謝謝您的幫助!
uj5u.com熱心網友回復:
您可以將函式指標存盤在里面struct Bird并添加一個輔助方法來獲得您想要的語法。
struct Bird {
name: String,
fly_impl: fn(&Bird) -> (),
}
impl Bird {
fn new(name: String, fly_impl: fn(&Bird) -> ()) -> Bird {
Bird { name, fly_impl }
}
fn fly(self: &Bird) {
(self.fly_impl)(self)
}
}
fn behavior1(b: &Bird) {
println!("{} behavior1", b.name);
}
fn behavior2(b: &Bird) {
println!("{} behavior2", b.name);
}
fn main() {
let captured_variable = 10;
let birds = vec![
Bird::new("Bird1".into(), behavior1),
Bird::new("Bird2".into(), behavior2),
Bird::new("Bird3".into(), |b| println!("{} lambda", b.name)),
/*Bird::new("Bird4".into(), |b| {
println!("{} lambda with {}", b.name, captured_variable)
}),*/
];
(birds[0].fly_impl)(&birds[0]);
for bird in birds {
bird.fly();
}
}
fn不要與trait Fn. 前者只允許函式和非捕獲 lambdas 并且具有固定大小。后者允許任意大小的任意捕獲,因此需要一些像Box. 兩者都在呼叫時進行動態調度。
請注意如何Bird3由非捕獲 lambda 指定的行為,這是允許的。但是,如果您嘗試取消注釋Bird4,該示例將無法編譯,因為其所需的行為是捕獲 lambda,它通常可以變得任意大,并且我們已禁止Boxes 和其他間接方式。
我對 Rust 的了解不夠多,無法告訴您是否有更類似于 Rust 的解決方案。但是,您的情況非常具體:
- 您有一個任意可擴展的
Birds層次結構。否則enum更適合。 - 但是,
Bird此層次結構中的所有s 都具有完全相同的一組欄位和traits 支持。否則,您必須通過 使用traits 和標準動態調度Box<dyn Bird>。 - 您不希望為單個
Birds分配堆。否則,您可以使用traits 和標準動態調度。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/348572.html
上一篇:我需要將'jonathan-morón-16394669'轉換為'jonathan-morón-16394669'
