如何创建实现共同特征的静态对象数组?
How to create a static array of objects that implement a common trait?
我正在尝试创建一个实现共同特征的静态对象数组。所有这些结构及其大小在编译时都是已知的。但是当访问在结构上定义的字段时,编译器告诉我该字段不在类型上。
fn main() {
for &thing in ALL_THINGS {
println!("{}", thing.name)
}
}
trait Thing: Sync { }
struct SpecificThing {
name: &'static str
}
impl Thing for SpecificThing { }
static ALL_THINGS: &'static [&dyn Thing] = &[&SpecificThing {name: "test"}];
error[E0609]: no field `name` on type `&dyn Thing`
--> src/main.rs:3:30
|
3 | println!("{}", thing.name)
| ^^^^
问题 , , Can I have a static borrowed reference to a trait object? or Vector of objects belonging to a trait 无助于解释为什么会发生这种情况或如何解决它。
请问我做错了什么?有没有更好的方法来解决我还没有找到的这个任务?
您无法从 &dyn Thing
访问 SpecificThing.name
,因为并非所有 Things
都有 name
字段(忽略特征没有字段的事实) .
您对 dyn Thing
的使用表明您有一组具有某些共同点的对象 (structs/enums)。所有这些共性都必须存在于 Thing
中,您才能访问它们。例如,如果名称很常见,您可以添加一个获取名称的函数:
fn main() {
for &thing in ALL_THINGS {
println!("{}", thing.get_name())
}
}
trait Thing: Sync {
fn get_name(&self) -> &'static str;
}
struct SpecificThing {
name: &'static str
}
impl Thing for SpecificThing {
fn get_name(&self) -> &'static str {
self.name
}
}
static ALL_THINGS: &'static [&dyn Thing] = &[&SpecificThing {name: "test"}];
当你定义&dyn Thing
时,你删除了关于特定数据类型的所有信息。这意味着您无法访问动态调度对象的字段。
想象一下 ALL_THINGS
中有两个不同的结构:
struct SpecificThing {
name: &'static str
}
struct SpecificAnotherThing {
no_name: &'static str
}
static ALL_THINGS: &'static [&dyn Thing] = &[&SpecificThing {name: "test"}, &SpecificAnotherThing { no_name: "" }];
您无法访问 name
字段,因为特征 Thing
对其实现的具体类型一无所知。因此您不能直接访问它的字段。
如果你真的需要它,你应该在 Thing
特征中定义一个方法,它将 return 你需要的值:
trait Thing: Sync {
fn name(&self) -> &str;
}
// ...
// ...
impl Thing for SpecificThing {
fn name(&self) -> &str {
self.name
}
}
或者您可以使用静态调度和代数数据类型 (enum
)。
我正在尝试创建一个实现共同特征的静态对象数组。所有这些结构及其大小在编译时都是已知的。但是当访问在结构上定义的字段时,编译器告诉我该字段不在类型上。
fn main() {
for &thing in ALL_THINGS {
println!("{}", thing.name)
}
}
trait Thing: Sync { }
struct SpecificThing {
name: &'static str
}
impl Thing for SpecificThing { }
static ALL_THINGS: &'static [&dyn Thing] = &[&SpecificThing {name: "test"}];
error[E0609]: no field `name` on type `&dyn Thing`
--> src/main.rs:3:30
|
3 | println!("{}", thing.name)
| ^^^^
问题
请问我做错了什么?有没有更好的方法来解决我还没有找到的这个任务?
您无法从 &dyn Thing
访问 SpecificThing.name
,因为并非所有 Things
都有 name
字段(忽略特征没有字段的事实) .
您对 dyn Thing
的使用表明您有一组具有某些共同点的对象 (structs/enums)。所有这些共性都必须存在于 Thing
中,您才能访问它们。例如,如果名称很常见,您可以添加一个获取名称的函数:
fn main() {
for &thing in ALL_THINGS {
println!("{}", thing.get_name())
}
}
trait Thing: Sync {
fn get_name(&self) -> &'static str;
}
struct SpecificThing {
name: &'static str
}
impl Thing for SpecificThing {
fn get_name(&self) -> &'static str {
self.name
}
}
static ALL_THINGS: &'static [&dyn Thing] = &[&SpecificThing {name: "test"}];
当你定义&dyn Thing
时,你删除了关于特定数据类型的所有信息。这意味着您无法访问动态调度对象的字段。
想象一下 ALL_THINGS
中有两个不同的结构:
struct SpecificThing {
name: &'static str
}
struct SpecificAnotherThing {
no_name: &'static str
}
static ALL_THINGS: &'static [&dyn Thing] = &[&SpecificThing {name: "test"}, &SpecificAnotherThing { no_name: "" }];
您无法访问 name
字段,因为特征 Thing
对其实现的具体类型一无所知。因此您不能直接访问它的字段。
如果你真的需要它,你应该在 Thing
特征中定义一个方法,它将 return 你需要的值:
trait Thing: Sync {
fn name(&self) -> &str;
}
// ...
// ...
impl Thing for SpecificThing {
fn name(&self) -> &str {
self.name
}
}
或者您可以使用静态调度和代数数据类型 (enum
)。