我有许多实现特征的结构,并且我需要一个函数根据运行时条件返回其中一个结构的实例。我也很难找出
new()
方法的签名,但我猜这两个是相关的。
结构体定义示例
trait Example {
fn new<T>() -> T where T: Example;
fn do_something(&self) {
//something to do
}
}
struct Ex1 {
some_attr: String
}
struct Ex2 {
some_attr: String
}
impl Example for Ex1 {
fn new<T>() -> T where T: Example {
Ex1{ some_attr: "".to_string() }
}
}
impl Example for Ex2 {
fn new<T>() -> T where T: Example {
Ex2{ some_attr: "".to_string() }
}
}
主要/功能示例
fn conditionally_generate_struct() -> Box<dyn Example> {
let condition = true;
return if condition {
Ex1::new()
} else {
Ex2::new()
}
}
let example = conditionally_generate_struct();
example.do_something();
在研究它时,我发现了一些方法,例如使用
Box
或 T
,但我不完全理解如何使用它们。说实话,我什至不知道如何归类这个问题。难道是泛型概念解决的问题?
在 Rust 中正确的做法是什么?我缺少什么概念?
trait Example {
fn new<T>() -> T where T: Example;
// ...
}
您(几乎肯定)不希望这样:这意味着可以在调用站点要求任何实现特征
Example
的类型返回也实现 Example
的任何其他类型。例如:
struct Foo; impl Example for Foo { ... }
struct Bar; impl Example for Bar { ... }
// callsite
let foo = Foo;
let bar: Bar = foo.new::<Bar>();
Self
的地方,它是一种代表“当前类型”的类型,即写在impl
块顶部的类型。
trait Example {
fn new() -> Self;
}
struct Foo;
impl Example for Foo {
fn new() -> Self { Foo }
}
struct Bar;
impl Example for Bar {
fn new() -> Self { Bar }
}
然而,在这种特定情况下,
new
似乎完全没有必要,除非你的代码库中有一些你没有在OP中解释的内容。这是因为没有实际的共享行为:它只是结构的构造。当你可以简单地调用 <Foo as Example>::new()
甚至直接构造 Foo::new()
时,为什么要调用 Foo { .. }
呢?结果是一样的。
对于你问题的第二部分:
fn conditionally_generate_struct() -> Box<dyn Example> {
let condition = true;
if condition {
Box::new(Ex1 { .. })
} else {
Box::new(Ex2 { .. })
}
}
let example = conditionally_generate_struct();
example.do_something();
要返回
Box
,您需要实际构造一个 Box
。实现特征的结构不会自动转换为盒装特征对象,因为这可能是一把枪。
还要再次注意,结构是直接构造的,而不是调用不必要的特征方法。