在 Rust 中构造一个对象数组
Construct an array of objects in Rust
这是我第一个真正有目的的 Rust 程序,但我仍然对语法一头雾水。所以我有这样的特征对象:
trait HC<'a> {
fn info(&self) -> TestInfo<'static>;
fn test(&self) -> HCResult<'a>;
}
#[allow(non_camel_case_types)]
struct Test_NTP;
impl<'a> HC<'a> for Test_NTP {
fn info(&self) -> TestInfo<'static> {
TestInfo { ... }
}
fn test(&self) -> HCResult<'a> {
...
}
}
#[allow(non_camel_case_types)]
struct Test_Last;
impl<'a> HC<'a> for Test_Last {
fn info(&self) -> TestInfo<'static> {
TestInfo { ... }
}
fn test(&self) -> HCResult<'a> {
...
}
}
我想构建一个由这些定义 HC 特征的对象组成的数组,与 ID 成组,这样我就可以遍历它们并调用它们的 test()
函数。
const HC_TESTS: [(i16, &dyn HC)] = [
(1, &Test_NTP),
(2, &Test_Last)
];
我尝试了几种变体,但总是收到“在编译时没有已知大小”错误。我以为将对象放入 Boxes 中可以解决问题,但我得到了同样的错误:
error[E0277]: the size for values of type `[(i16, Box<&'static (dyn HC<'static> + 'static)>)]` cannot be known at compilation time
--> src/hc.rs:125:17
|
125 | const HC_TESTS: [(i16, Box<&dyn HC>)] = [
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[(i16, Box<&'static (dyn HC<'static> + 'static)>)]`
结构没有任何字段,我使用它们的唯一原因是将 info()
和 test()
函数绑定在一起,我什至不使用 &self
,它们只需要分派虚拟方法。我做错了什么?
你的问题是你不能使用&
(you actually can,问题是你实际上没有设置数组长度 [(i16, &dyn HC); 2]
).
您也可以使用 Box
。但是由于 Box::new
不是 const
,您需要将其包装在其他一些惰性包装器中,std::lazy::Lazy
不是稳定的 jet 但可以工作:
const HC_TESTS: Lazy<[(i16, Box<dyn HC>); 2]> = Lazy::new(|| [
(1, Box::new(Test_NTP)),
(2, Box::new(Test_Last))
]);
另一种选择是将它们全部包装在一个 enum
中,这样您就可以构造它们,并为该枚举实现特征,以便您以后可以使用它:
enum Tests {
NTP(Test_NTP),
Last(Test_Last)
}
impl<'a> HC<'a> for Tests {
fn info(&self) -> TestInfo<'static> {
match self {
Self::NTP(e) => e.info(),
Self::Last(e) => e.info()
}
}
fn test(&self) -> HCResult<'a> {
match self {
Self::NTP(e) => e.test(),
Self::Last(e) => e.test()
}
}
}
const HC_TESTS: [(i16, Tests); 2] = [
(1, Tests::NTP(Test_NTP)),
(2, Tests::Last(Test_Last))
];
您的语法略有偏差。错误
the trait `Sized` is not implemented for `[(i16, Box<&'static (dyn HC<'static> + 'static)>)]
指的是最外面的[...]
,也就是一个slice
.
在
const HC_TESTS: [(i16, Box<&dyn HC>)] =
您将 HC_TESTS
的类型明确设置为 slice
,而不是 array
。切片总是没有大小,所以编译器会抱怨。你想要的只是
const HC_TESTS: [(i16, Box<&dyn HC>); 2] =
将 HC_TESTS
的类型设置为恰好两个元素的 array
。
请注意,此处的其他答案和评论(“对我有用”)也使用此语法。
这是我第一个真正有目的的 Rust 程序,但我仍然对语法一头雾水。所以我有这样的特征对象:
trait HC<'a> {
fn info(&self) -> TestInfo<'static>;
fn test(&self) -> HCResult<'a>;
}
#[allow(non_camel_case_types)]
struct Test_NTP;
impl<'a> HC<'a> for Test_NTP {
fn info(&self) -> TestInfo<'static> {
TestInfo { ... }
}
fn test(&self) -> HCResult<'a> {
...
}
}
#[allow(non_camel_case_types)]
struct Test_Last;
impl<'a> HC<'a> for Test_Last {
fn info(&self) -> TestInfo<'static> {
TestInfo { ... }
}
fn test(&self) -> HCResult<'a> {
...
}
}
我想构建一个由这些定义 HC 特征的对象组成的数组,与 ID 成组,这样我就可以遍历它们并调用它们的 test()
函数。
const HC_TESTS: [(i16, &dyn HC)] = [
(1, &Test_NTP),
(2, &Test_Last)
];
我尝试了几种变体,但总是收到“在编译时没有已知大小”错误。我以为将对象放入 Boxes 中可以解决问题,但我得到了同样的错误:
error[E0277]: the size for values of type `[(i16, Box<&'static (dyn HC<'static> + 'static)>)]` cannot be known at compilation time
--> src/hc.rs:125:17
|
125 | const HC_TESTS: [(i16, Box<&dyn HC>)] = [
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[(i16, Box<&'static (dyn HC<'static> + 'static)>)]`
结构没有任何字段,我使用它们的唯一原因是将 info()
和 test()
函数绑定在一起,我什至不使用 &self
,它们只需要分派虚拟方法。我做错了什么?
你的问题是你不能使用(you actually can,问题是你实际上没有设置数组长度 &
[(i16, &dyn HC); 2]
).
您也可以使用 Box
。但是由于 Box::new
不是 const
,您需要将其包装在其他一些惰性包装器中,std::lazy::Lazy
不是稳定的 jet 但可以工作:
const HC_TESTS: Lazy<[(i16, Box<dyn HC>); 2]> = Lazy::new(|| [
(1, Box::new(Test_NTP)),
(2, Box::new(Test_Last))
]);
另一种选择是将它们全部包装在一个 enum
中,这样您就可以构造它们,并为该枚举实现特征,以便您以后可以使用它:
enum Tests {
NTP(Test_NTP),
Last(Test_Last)
}
impl<'a> HC<'a> for Tests {
fn info(&self) -> TestInfo<'static> {
match self {
Self::NTP(e) => e.info(),
Self::Last(e) => e.info()
}
}
fn test(&self) -> HCResult<'a> {
match self {
Self::NTP(e) => e.test(),
Self::Last(e) => e.test()
}
}
}
const HC_TESTS: [(i16, Tests); 2] = [
(1, Tests::NTP(Test_NTP)),
(2, Tests::Last(Test_Last))
];
您的语法略有偏差。错误
the trait `Sized` is not implemented for `[(i16, Box<&'static (dyn HC<'static> + 'static)>)]
指的是最外面的[...]
,也就是一个slice
.
在
const HC_TESTS: [(i16, Box<&dyn HC>)] =
您将 HC_TESTS
的类型明确设置为 slice
,而不是 array
。切片总是没有大小,所以编译器会抱怨。你想要的只是
const HC_TESTS: [(i16, Box<&dyn HC>); 2] =
将 HC_TESTS
的类型设置为恰好两个元素的 array
。
请注意,此处的其他答案和评论(“对我有用”)也使用此语法。