Rust:重构后结构的可见性现已公开;无法将main添加到发布(在板条箱::main中)
我对锈菌还比较陌生,因此以下可能也是对一个概念的误解: 我从中获取了ggez基本项目模板,如下所示:Rust:重构后结构的可见性现已公开;无法将main添加到发布(在板条箱::main中),rust,visibility,Rust,Visibility,我对锈菌还比较陌生,因此以下可能也是对一个概念的误解: 我从中获取了ggez基本项目模板,如下所示: use ggez::{graphics, Context, ContextBuilder, GameResult}; use ggez::event::{self, EventHandler}; fn main() { // Make a Context. let (mut ctx, mut event_loop) = ContextBuilder::new("my_
use ggez::{graphics, Context, ContextBuilder, GameResult};
use ggez::event::{self, EventHandler};
fn main() {
// Make a Context.
let (mut ctx, mut event_loop) = ContextBuilder::new("my_game", "Cool Game Author")
.build()
.expect("aieee, could not create ggez context!");
// Create an instance of your event handler.
// Usually, you should provide it with the Context object to
// use when setting your game up.
let mut my_game = MyGame::new(&mut ctx);
// Run!
match event::run(&mut ctx, &mut event_loop, &mut my_game) {
Ok(_) => println!("Exited cleanly."),
Err(e) => println!("Error occured: {}", e)
}
}
struct MyGame {
// Your state here...
}
impl MyGame {
pub fn new(_ctx: &mut Context) -> MyGame {
// Load/create resources such as images here.
MyGame {
// ...
}
}
}
impl EventHandler for MyGame {
fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
// Update code here...
Ok(())
}
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
graphics::clear(ctx, graphics::WHITE);
// Draw code here...
graphics::present(ctx)
}
}
src
|---main.rs
|---game
|---mod.rs
|---game.rs
|---init.rs
并将其添加到game.rs
use ggez::event::EventHandler;
use ggez::{Context, GameResult, graphics};
只要我把MyGame
公之于众,一切都能正常工作
然而,现在重构正在发生巨大的变化,因为MyGame以前是私有的。
我用pub(在infinite_runner::main中)
和类似的方法尝试了几种方法,比如cratet::main
,但没有一种方法被各种错误消息接受
现在我的问题是,有没有一种方法可以将
MyGame
公开给main.rs
而不向任何其他人公开?main似乎不是一个有效的目标。我通过在rust文档中反复强调,设法找到了它。
虽然回答我自己的问题有点可疑,但实际上可能对其他人有所帮助:
TLDR;
我们希望主函数内的代码可以访问MyGame,但外部的任何其他模块都被拒绝访问
是否可以将代码分解到游戏中。rs
:否
能做到吗?是的
以下是原因和方式:
根据防锈文件:
由于物品可以是公共的,也可以是私人的,所以生锈是允许的
两种情况下的项目访问:
main.rs
位于顶层,因此整个板条箱可以访问与任何其他模块相同级别的任何公共内容,因为每个模块都可以访问顶层的父模块。
因此,重构到同一级别的文件(模块)的答案是:否
另一方面,如果我将代码分解成一个名为lib.rs
的文件,那么唯一的区别就是路径,因为顶层的lib.rs
隐式地只是crater
路径,而在名为game.rs
的文件中,路径将是crater::game
但是,通过垂直分解,可以实现与单个文件相同的行为。我们创建一个名为game
的目录,并将game.rs
移动到此目录中,并将pub关键字添加到MyGame:pub struct MyGame
。
类似于python\uuuu init\uuuuupy.py
文件,rust需要一个文件mod.rs
,以使目录成为一个模块。
在mod.rs
中,您声明了您拥有的文件,在本例中,mod game
。
现在我们可以通过路径crater::game::game::MyGame
来解决MyGame,但是由于game.rs
被声明为私有,因此对MyGame的访问是密封的,因为路径的所有元素都必须是公共的。
但是,由于MyGame是公开的,所以同一级别的任何模块都可以访问它。
我们不能将main.rs
移动到游戏目录中,但我们可以将其中的代码分解到另一个函数中。让我们称之为init
,因为缺乏幻想。我们将init函数放在游戏目录中名为init.rs
的文件中,并在mod.rs
中声明为public,如下所示:pub mod init
。
现在我们可以调用game::init::init()
,因为它是公共的,但不是game::game::MyGame
。但是,Init可以访问MyGame
最终结构如下所示:
use ggez::{graphics, Context, ContextBuilder, GameResult};
use ggez::event::{self, EventHandler};
fn main() {
// Make a Context.
let (mut ctx, mut event_loop) = ContextBuilder::new("my_game", "Cool Game Author")
.build()
.expect("aieee, could not create ggez context!");
// Create an instance of your event handler.
// Usually, you should provide it with the Context object to
// use when setting your game up.
let mut my_game = MyGame::new(&mut ctx);
// Run!
match event::run(&mut ctx, &mut event_loop, &mut my_game) {
Ok(_) => println!("Exited cleanly."),
Err(e) => println!("Error occured: {}", e)
}
}
struct MyGame {
// Your state here...
}
impl MyGame {
pub fn new(_ctx: &mut Context) -> MyGame {
// Load/create resources such as images here.
MyGame {
// ...
}
}
}
impl EventHandler for MyGame {
fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
// Update code here...
Ok(())
}
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
graphics::clear(ctx, graphics::WHITE);
// Draw code here...
graphics::present(ctx)
}
}
src
|---main.rs
|---game
|---mod.rs
|---game.rs
|---init.rs
main.rs:
mod game;
use game::init;
fn main() {
init::init();
}
国防部:
pub mod init;
mod game;
game.rs:
use ggez::event::EventHandler;
use ggez::{graphics, Context, GameResult};
pub struct MyGame {
// Your state here...
}
impl MyGame {
pub fn new(_ctx: &mut Context) -> MyGame {
// Load/create resources such as images here.
MyGame {
// ...
}
}
}
impl EventHandler for MyGame {
fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
// Update code here...
Ok(())
}
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
graphics::clear(ctx, graphics::WHITE);
// Draw code here...
graphics::present(ctx)
}
}
我想说,这是一个普遍的做法,一个板条箱的模块有更多的访问,他们需要。因此,我不认为pub struct MyGame有问题。我不确定这是否没有问题,因为该结构不仅暴露在板条箱内部,而且暴露在任何其他模块之外。如果MyGame是某种实现细节(这就是为什么它最初是私有的),那么我现在已经向外界公开了这个实现细节,这肯定不是我想要的。我假设
pub(in)
是为了解决这个问题,但是我不知道如何将main.rs
文件作为目标。pub(claiter)struct MyGame对你有用吗?@Kitsu谢谢你的帮助。这将编译结构,但也将结构暴露给板条箱内外的任何其他模块。然而,我们想要的是将我的游戏与我的主函数中的代码之外的任何东西隔离开来。请参阅我的答案,以获取解决此问题的方法。