问题描述
我有4个文件:
main.rs
main.rs
mod bar;
fn main() {
let v = vec![1, 2, 3];
println!("Hello, world!");
}
lib.rs
lib.rs
pub mod foo;
pub mod bar;
foo.rs
foo.rs
pub fn say_foo() {
}
bar.rs
bar.rs
use crate::foo;
fn bar() {
foo::say_foo();
}
当我运行cargo run
时,我收到一条错误消息:
When I run cargo run
I get an error saying:
error[E0432]: unresolved import `crate::foo`
--> src/bar.rs:1:5
|
1 | use crate::foo;
| ^^^^^^^^^^ no `foo` in the root
有人可以向我解释如何解决此问题吗?更广泛地说:当存在main.rs
和lib.rs
时,模块查找如何工作?
Could someone explain to me how to fix this? A bit more broadly: how does module lookup work when there's a main.rs
and a lib.rs
?
将mod foo
添加到main.rs
可解决此问题.但是我不明白这一点-我给人的印象是lib.rs
是暴露"我所有模块的地方?为什么还要在main.rs
中声明模块?
Adding mod foo
to main.rs
fixes the issue. But I don't understand this -- I was under the impression the lib.rs
was the place that "exposed" all of my modules? Why do I have to declare the module in main.rs
as well?
我的Cargo.toml
:
[package]
name = "hello-world"
version = "0.1.0"
authors = ["[email protected]>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
推荐答案
让我们从头开始.请参阅包装布局一章://doc.rust-lang.org/cargo/index.html"rel =" noreferrer>《货运手册》 .如您所见,您的包裹中可能包含很多东西:
Let's start from the beginning. Look at the Package Layout chapter in The Cargo Book. As you can see, your package can contain lot of stuff:
- 一个二进制文件(您可以运行的东西)或多个二进制文件,
- 单个库(共享代码)
- 示例
- 基准,
- 集成测试.
此处未列出所有可能性,仅列出了二进制文件/库组合.
Not all of the possibilities are listed here, just the binary / library combinations.
这是具有单个二进制文件的软件包的示例.入口点是src/main.rs
中的main
函数.
This is an example of a package with single binary. Entry point is the main
function in the src/main.rs
.
Cargo.toml
:
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
src/main.rs
:
fn main() {
println!("Hallo, Rust here!")
}
$ cargo run
Hallo, Rust here!
图书馆
这是带有库的软件包的示例.库没有入口点,您不能运行它们.它们用于功能共享.
A library
This is an example of a package with a library. Libraries don't have entry points, you can't run them. They're used for functionality sharing.
Cargo.toml
:
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
src/lib.rs
:
pub fn foo() {
println!("Hallo, Rust library here!")
}
$ cargo run
error: a bin target must be available for `cargo run`
您是否在Cargo.toml
文件中看到有关二进制文件或库的任何内容?否.原因是我遵循了包装布局并且cargo
知道在哪里寻找东西.
Do you see anything in the Cargo.toml
file about a binary or a library? No. The reason is that I've followed the Package Layout and the cargo
knows where to look for things.
这是带有二进制文件和库的软件包的示例.
This is an example of a package with a binary and a library.
Cargo.toml
:
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
src/lib.rs
:
pub const GREETING: &'static str = "Hallo, Rust library here!";
src/main.rs
:
use hallo::GREETING;
fn main() {
println!("{}", GREETING);
}
相同的问题,您是否在Cargo.toml
文件中看到有关二进制文件或库的任何内容?不.
Same question, do you see anything in the Cargo.toml
file about a binary or a library? No.
此软件包包含两件事:
- 二进制文件(根目录
src/main.rs
,入口点src/main.rs::main
) - 一个库(根
src/lib.rs
,共享代码).
- a binary (root
src/main.rs
, entry pointsrc/main.rs::main
), - a library (root
src/lib.rs
, shared code).
可以通过use hallo::...
从二进制文件中引用库,其中hallo
是此程序包的名称(Cargo.toml
-> [package]
-> name
).
A library can be referenced from the binary via use hallo::...
where the hallo
is this package name (Cargo.toml
-> [package]
-> name
).
Cargo.toml
:
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
相同的包装布局
库的一部分
src/lib.rs
:
pub mod bar;
pub mod foo;
src/foo.rs
:
pub fn say_foo() {
println!("Foo");
}
src/bar.rs
:
use crate::foo;
pub fn bar() {
foo::say_foo();
}
crate
指的是src/lib.rs
,因为我们在这里是我们库的上下文.
crate
refers to src/lib.rs
, because we're in the context of our library here.
将其作为独立的单元进行处理,并通过use hallo::...;
进行引用.
Treat it as a standalone unit and refer to it via use hallo::...;
from the outside world.
src/main.rs
:
use hallo::bar::bar;
fn main() {
bar();
}
在这里,我们只是在使用我们的库.
Here we're just using our library.
相同的代码,但是lib.rs
被重命名为utils.rs
,并且(foo|bar).rs
文件被移动到src/utils/
文件夹.
Same code, but lib.rs
was renamed to utils.rs
and (foo|bar).rs
files were moved to the src/utils/
folder.
src/utils.rs
:
pub mod bar;
pub mod foo;
src/utils/foo.rs
:
pub fn say_foo() {
println!("Foo");
}
src/utils/bar.rs
:
use super::foo;
// or use crate::utils::foo;
pub fn bar() {
foo::say_foo();
}
我们也可以在这里使用crate
,但是由于我们处于二进制环境中,因此路径有所不同.
We can use crate
here as well, but because we're in the context of our binary, the path differs.
src/main.rs
:
use utils::bar::bar;
mod utils;
fn main() {
bar();
}
在这里,我们刚刚声明了另一个模块(utils
),我们正在使用它.
Here we just declared another module (utils
) and we're using it.
Cargo.toml
内容:
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
如果有src/main.rs
文件,则基本上是这样说的:
If there's a src/main.rs
file, you're basically saying this:
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[[bin]]
name = "hallo"
src = "src/main.rs"
如果有src/lib.rs
文件,您基本上是这样说的:
If there's a src/lib.rs
file, you're basically saying this:
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[lib]
name = "hallo"
path = "src/lib.rs"
如果两者都存在,基本上就是这样说:
If there're both of them, you're basically saying this:
[package]
name = "hallo"
version = "0.1.0"
edition = "2018"
[[bin]]
name = "hallo"
path = "src/main.rs"
[lib]
name = "hallo"
path = "src/lib.rs"
文档
- 包装布局
- 清单格式
- 使用程序包,板条箱和模块管理不断发展的项目
- Package Layout
- The Manifest Format
- Managing Growing Projects with Packages, Crates, and Modules
Documentation
这篇关于当存在main.rs和lib.rs时,Rust模块会感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!