我正在实现一个游戏引擎,并希望有一组模块,每个模块都实现某些规则。每个模块都公开一个符合此定义的功能:
fn validate(game: &Game, next_move: String) -> Result<(), MoveError>
而不是让每个规则模块的使用者都使用这些规则use
,我想公开这些验证函数的集合(array
?Vec<>
?)。我以为它将是一个函数指针数组,类似于:
mod rule1;
mod rule2;
type Validate = fn(&Game, String) -> Result<(), MoveError>;
const validations: [Validate] = &[
rule1::validate,
rule2::validate
];
但是Rust说:
error[E0277]: the size for values of type `[for<'r> fn(&'r Game, std::string::String) -> std::result::Result<(), MoveError>]` cannot be known at compilation time
--> src/lib.rs:6:20
|
6 | const validations: [Validate] = &[
| ^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[for<'r> fn(&'r Game, std::string::String) -> std::result::Result<(), MoveError>]`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
我已经阅读了链接的文章,没有一个人更明智。解决此错误(或纠正我缺乏了解的第一步)的第一步是什么]
您的问题与功能无关。
您可以使用以下方法重现它:
const validation: [u32] = &[ 42 ];
给出
error[E0277]: the size for values of type `[u32]` cannot be known at compilation time
--> src/lib.rs:1:19
|
1 | const validation: [u32] = &[ 42 ];
| ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[u32]`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
问题是,无论[T]
是什么,Sized
都不是T
类型。这意味着您无法在const
中使用它。
但是您可以使用参考:
const validation: &[u32] = &[ 42 ];
或大小合适的数组:
const validation: [u32; 1] = [ 42 ];
同样适用于您的原始问题:
const validations: &[Validate] = &[
// ^
rule1::validate,
rule2::validate
];
struct Game;
struct MoveError;
mod rule1 {
use super::*;
pub(crate) fn validate(game: &Game, s: String) -> Result<(), MoveError> {
unimplemented!()
}
}
mod rule2 {
use super::*;
pub(crate) fn validate(game: &Game, s: String) -> Result<(), MoveError> {
unimplemented!()
}
}
const VALIDATIONS: &[fn(&Game, String) -> Result<(), MoveError>] = &[
rule1::validate,
rule2::validate,
];
// or...
use lazy_static::lazy_static;
lazy_static! {
static ref VALIDATIONS_2: &[Box<dyn Fn(&Game, String) -> Result<(), MoveError>>] = &[
Box::new(rule1::validate),
Box::new(rule2::validate)
];
}