在Rust中,我可以从我的模块中公开一组函数吗?

问题描述 投票:1回答:2

我正在实现一个游戏引擎,并希望有一组模块,每个模块都实现某些规则。每个模块都公开一个符合此定义的功能:

fn validate(game: &Game, next_move: String) -> Result<(), MoveError>

而不是让每个规则模块的使用者都使用这些规则use,我想公开这些验证函数的集合(arrayVec<>?)。我以为它将是一个函数指针数组,类似于:

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>

我已经阅读了链接的文章,没有一个人更明智。解决此错误(或纠正我缺乏了解的第一步)的第一步是什么]

compiler-errors rust
2个回答
2
投票

您的问题与功能无关。

您可以使用以下方法重现它:

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
];

0
投票
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)
    ];    
}
© www.soinside.com 2019 - 2024. All rights reserved.