gpt4 book ai didi

Rust:对向量中结构的多态调用

转载 作者:行者123 更新时间:2023-11-29 08:18:13 24 4
gpt4 key购买 nike

我是 Rust 的新手,我正在尝试了解该语言的基础知识。

考虑以下特征

trait Function {
fn value(&self, arg: &[f64]) -> f64;
}

和两个实现它的结构:

struct Add {}

struct Multiply {}

impl Function for Add {
fn value(&self, arg: &[f64]) -> f64 {
arg[0] + arg[1]
}
}

impl Function for Multiply {
fn value(&self, arg: &[f64]) -> f64 {
arg[0] * arg[1]
}
}

在我的 main() 函数中,我想将 AddMultiply 的两个实例分组到一个向量中,然后调用 方法。以下作品:

fn main() {
let x = vec![1.0, 2.0];
let funcs: Vec<&dyn Function> = vec![&Add {}, &Multiply {}];

for f in funcs {
println!("{}", f.value(&x));
}
}

也是如此:

fn main() {
let x = vec![1.0, 2.0];
let funcs: Vec<Box<dyn Function>> = vec![Box::new(Add {}), Box::new(Multiply {})];

for f in funcs {
println!("{}", f.value(&x));
}
}

有没有更好/更简洁的方法?我可以解决将实例包装在 Box 中的问题吗?在这种情况下,特征对象的要点是什么?

最佳答案

Is there any better / less verbose way?

没有真正的方法可以使它不那么冗长。由于您使用的是特征对象,因此您需要告诉编译器向量的项是 dyn Function 而不是具体类型。编译器不能仅仅推断出您指的是 dyn Function 特征对象,因为 AddMultiply 都可以实现其他特征。

您也不能抽象出对 Box::new 的调用。为此,您必须以某种方式映射异构集合,这在 Rust 中是不可能的。但是,如果您经常编写此代码,则可以考虑为每个具体的 impl 添加辅助构造函数:

impl Add {
fn new() -> Add {
Add {}
}

fn new_boxed() -> Box<Add> {
Box::new(Add::new())
}
}

尽可能包含new 构造函数是惯用的做法,但包含其他方便的构造函数也很常见。

这使得向量的构造变得不那么嘈杂:

let funcs: Vec<Box<dyn Function>> = vec!(Add::new_boxed(), Multiply::new_boxed()));

What is the takeaway with trait objects in this case?

使用动态调度总是会对性能造成小的影响。如果你所有的对象都是同一类型,它们可以密集地存放在内存中,这样迭代速度会快得多。一般来说,我不会太担心这个,除非你正在创建一个库箱,或者如果你真的想挤出最后一纳秒的性能。

关于Rust:对向量中结构的多态调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53897315/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com