Module 如果存在main.rs和lib.rs,则会导致模块混淆

Module 如果存在main.rs和lib.rs,则会导致模块混淆,module,rust,Module,Rust,我有4个文件: main.rs mod bar; fn main() { let v = vec![1, 2, 3]; println!("Hello, world!"); } pub mod foo; pub mod bar; pub fn say_foo() { } use crate::foo; fn bar() { foo::say_foo(); } lib.rs mod bar; fn main() { let v = vec![1

我有4个文件:

main.rs

mod bar;

fn main() {
    let v = vec![1, 2, 3];
    println!("Hello, world!");
}
pub mod foo;
pub mod bar;

pub fn say_foo() {

}

use crate::foo;

fn bar() {
    foo::say_foo();
}

lib.rs

mod bar;

fn main() {
    let v = vec![1, 2, 3];
    println!("Hello, world!");
}
pub mod foo;
pub mod bar;

pub fn say_foo() {

}

use crate::foo;

fn bar() {
    foo::say_foo();
}

foo.rs

mod bar;

fn main() {
    let v = vec![1, 2, 3];
    println!("Hello, world!");
}
pub mod foo;
pub mod bar;

pub fn say_foo() {

}

use crate::foo;

fn bar() {
    foo::say_foo();
}

bar.rs

mod bar;

fn main() {
    let v = vec![1, 2, 3];
    println!("Hello, world!");
}
pub mod foo;
pub mod bar;

pub fn say_foo() {

}

use crate::foo;

fn bar() {
    foo::say_foo();
}

当我运行
cargo run
时,我会收到一个错误,提示:

错误[E0432]:未解析的导入`crate::foo`
-->钢筋混凝土/钢筋混凝土:1:5
|
1 |使用板条箱::foo;
|^^^^^^^^^^^^根目录中没有'foo'
有人能给我解释一下怎么解决这个问题吗?更广泛一点:当有
main.rs
lib.rs
时,模块查找是如何工作的

编辑:将
mod foo
添加到
main.rs
修复了该问题。但我不明白这一点——我的印象是
lib.rs
是“暴露”我所有模块的地方?为什么还要在
main.rs
中声明模块

My
Cargo.toml

[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[软件包]
name=“你好,世界”
version=“0.1.0”
作者=[”me@mgail.com>"]
edition=“2018”
#请参阅上的更多关键点及其定义https://doc.rust-lang.org/cargo/reference/manifest.html
[依赖关系]

lib.rs
main.rs
文件是包的两个独立入口点

当您使用
cargo run
(或构建二进制文件并显式运行它)时,要使用的入口点是
main.rs
,而
crater
关键字指的是二进制文件箱。它甚至不必知道在
lib.rs
中有什么东西:二进制文件将像对待任何其他外部板条箱一样对待库,并且必须通过
extern板条箱hello\u world
导入,例如,
使用hello\u world::foo

但是,导入库时,入口点是
lib.rs
,而
板条箱是库板条箱。在本例中,是的,您添加到
lib.rs
中的所有内容都将暴露在整个板条箱中

在这种情况下,通常的工作流程是使二进制文件类似于库的薄包装器—在某些极端情况下,
main.rs
只包含以下内容

use library;
fn main() {
    library::main();
}

整个逻辑(以及所有的项目结构)都放进了图书馆的板条箱。其中一个原因正是您遇到的:可能会混淆此具体模块是否在包装的每个板条箱中导入。

让我们从头开始。请看中的章节。正如您所看到的,您的包可以包含很多内容:

  • 一个二进制文件(可以运行的东西)或多个二进制文件
  • 单个库(共享代码)
  • 示例
  • 基准
  • 集成测试
包装布局 这里并没有列出所有的可能性,只是二进制/库的组合

二进制文件 这是一个包含单个二进制文件的包的示例。入口点是
src/main.rs
中的
main
函数

Cargo.toml

[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
src/main.rs

fn main(){
println!(“喂,这里生锈了!”)
}
$cargo run
喂,这里生锈了!
图书馆 这是一个带有库的包的示例。库没有入口点,您无法运行它们。它们用于功能共享

Cargo.toml

[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
src/lib.rs

pub fn foo(){
println!(“喂,这里是锈库!”)
}
$cargo run
错误:bin目标必须可用于“货物运行”`
您在
Cargo.toml
文件中看到关于二进制文件或库的任何内容吗?没有。原因是我一直在跟踪,而且
货物
知道在哪里找东西

二进制文件和库 这是一个包含二进制文件和库的包的示例

Cargo.toml

[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
src/lib.rs

pub const问候语:&'static str=“你好,这里是锈迹斑斑的图书馆!”;
src/main.rs

使用hallo::问候语;
fn main(){
println!(“{}”,问候语);
}
同样的问题,您在
Cargo.toml
文件中看到关于二进制文件或库的任何内容吗?没有

此软件包包含两个内容:

  • 二进制文件(根
    src/main.rs
    ,入口点
    src/main.rs::main
  • 库(root
    src/lib.rs
    ,共享代码)
可以通过
使用hallo::…
从二进制文件中引用库,其中
hallo
是此包名(
Cargo.toml
->
[package]
->
name

你的问题
Cargo.toml

[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
相同的包装布局 图书馆的一部分
src/lib.rs

pub mod bar;
酒店;
src/foo.rs

pub fn say_foo(){
println!(“Foo”);
}
src/bar.rs

使用板条箱::foo;
酒吧{
foo::say_foo();
}

cratet
指的是
src/lib.rs
,因为我们在这里的库的上下文中

将其视为一个独立的单元,并通过
使用hallo::来自外部世界

二元部分
src/main.rs

使用hallo::bar::bar;
fn main(){
bar();
}
我们只是在用我们的图书馆

没有图书馆 相同的代码,但是
lib.rs
被重命名为
utils.rs
(foo | bar)。rs
文件被移动到
src/utils/
文件夹

src/utils.rs

pub mod bar;
酒店;
src/utils/foo.rs

pub fn say_foo(){
println!(“Foo”);
}
src/utils/bar.rs

使用super::foo;
//或者使用板条箱::utils::foo;
酒吧{
foo::say_foo();
}
我们也可以在这里使用
crater
,但是因为我们处于二进制文件的上下文中,所以路径不同

src/main.rs

使用utils::bar::bar;
mod utils;