gpt4 book ai didi

Rust:重构后结构的可见性现在公开;无法将 main 添加到 pub(在 crate::main 中)

转载 作者:行者123 更新时间:2023-12-03 11:29:54 27 4
gpt4 key购买 nike

我对 rust 比较陌生,所以以下也可能是对一个概念的误解:
我从 basic project template 中获取了 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_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)
}
}
并将其重构为两个文件 main.rsgame.rs第一个刚刚包含 main()函数,其他的都进入 game.rs .
main.rs 中更改导入后到
mod game;

use game::MyGame;
use ggez::{graphics, Context, ContextBuilder, GameResult};
use ggez::event::{self, EventHandler};
并将其添加到 game.rs
use ggez::event::EventHandler;
use ggez::{Context, GameResult, graphics};
一切正常,只要我做 MyGame上市。
然而,现在重构正在发生巨大的变化,因为 MyGame 之前是私有(private)的。
我尝试了几种方法 pub (in infinite_runner::main)和类似的,例如 crate::main但没有接受各种错误消息。
现在我的问题是,有没有办法暴露 MyGamemain.rs不暴露给其他人?似乎 main 不是一个有效的目标。

最佳答案

通过重申 rust 文档,我设法弄清楚了。
虽然回答我自己的问题感觉有点可疑,但实际上可能对其他人有帮助:
TLDR;
我们希望 main 函数内的代码能够访问 MyGame,但外部的任何其他模块都拒绝访问。
是否可以将代码分解为 game.rs : 不。
是否可以做到:是的。
以下是原因和方法:
来自 rust 文档 Visibility and Privacy :

With the notion of an item being either public or private, Rust allowsitem accesses in two cases:

  1. If an item is public, then it can be accessed externally from somemodule m if you can access all the item's parent modules from m. Youcan also potentially be able to name the item through re-exports. Seebelow.
  2. If an item is private, it may be accessed by the current moduleand its descendants.

这意味着我不能横向考虑并期望同时横向限制。由于 main.rs位于顶层的任何相同级别的公共(public)内容都可以像任何其他模块一样被整个 crate 访问,因为每个模块都可以访问顶层的父级。
因此,将同一级别重构为文件(模块)的答案是:否。
附带说明一下,如果我将代码分解到一个名为 lib.rs 的文件中那么唯一的区别就是路径,如 lib.rs顶层隐含的只是 crate路径,而在名为 game.rs 的文件中路径将是 crate::game .
但是可以通过垂直分解来完成与单个文件相同的行为。我们创建一个名为 game 的目录并移动 game.rs在此目录中并将 pub 关键字添加到 MyGame: pub struct MyGame .
类似于 python __init__.py文件 rust 需要一个文件 mod.rs使目录成为模块。
里面 mod.rs你声明你里面的文件, mod game在我们的例子中。
现在我们可以通过路径 crate::game::game::MyGame 来寻址 MyGame。 , 但是自从 game.rs被声明为私有(private),对 MyGame 的访问是密封的,因为路径的所有元素都必须是公共(public)的。
但是,由于 MyGame 被声明为 public,因此同一级别的任何模块都可以访问它。
我们无法移动 main.rs进入游戏目录,但我们可以将其中的代码分解为另一个函数。我们就叫它 init因为缺乏幻想。我们将 init 函数放在一个名为 init.rs 的文件中。在游戏目录中并在 mod.rs 中将其声明为 public像这样: pub mod init .
现在我们可以调用 game::init::init()因为它是公开的,但不是 game::game::MyGame .然而,Init 可以访问 MyGame .
最终结构如下所示:
src
|---main.rs
|---game
|---mod.rs
|---game.rs
|---init.rs
main.rs:
mod game;
use game::init;

fn main() {
init::init();
}
模组.rs:
pub mod init;
mod 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)
}
}
初始化.rs:
use crate::game::game::MyGame;
use ggez::{ContextBuilder, event};

pub fn init() {
// 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),
}
}

关于Rust:重构后结构的可见性现在公开;无法将 main 添加到 pub(在 crate::main 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62603528/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com