Why can't I import module from different file

2020-02-15 01:51发布

问题:

My directory structure:

src
    main.rs
    image.rs
    decoders.rs

When I try to import my decoders module in image.rs I get this:

error[E0583]: File not found for module `decoders`

decoders.rs:

pub mod Decoders {}

image.rs:

mod decoders

use decoders::Decoders

pub mod Image {}

Note: I am using a module that wraps the entire file on purpose that's I can put attributes on entire files. This is why it's not a duplicate of How to include module from another file from the same project?

The weird thing is, is that this syntax works perfectly fine when I try to import Image in main.rs:

mod image;

use image::Image;

回答1:

What's happening is that when you try to import decoders::Decoders in image.rs, you need to go through the next level up, because using this:

mod decoders

use decoders::Decoders

Means that decoders will now be "owned" or under image, which is impossible since only lib.rs, mod.rs or main.rs files can have modules in other files. So, to fix this, you can either change your file structure to this:

src
    main.rs
    image
        mod.rs
        decoder.rs

Or, use this in main.rs:

mod decoders;
mod image;

and this in image.rs:

use super::decoders::Decoders;
//Or alternatively
use crate::decoders::Decoders;

Also, to fix your nested-mod problem, do the following in decoders.rs:

//Your code, no `mod Decoders`

and the following where you have your mod decoders statement:

#[your_attribs]
mod decoders;


回答2:

The rust compiler resolves modules differently depending on where they're defined.

When you use the mod keyword to declare an external module from the crate entry point (typically main.rs or lib.rs) or from a module root (mod.rs), the compiler will search for files adjacent to the declaring file. This is why it works properly when using mod image.rs in your main.rs file.

In other cases, the compiler will search for files in the folder with the same name as the declaring file. In your case, this means that your mod decoders; line in image.rs results in the compiler searching for the module in the image subfolder - specifically checking image/decoders.rs and image/decoders/mod.rs.

To fix this, you can either move decoders.rs to image/decoders.rs if you want to keep decoders as a submodule of image, or alternatively place mod decoders; in main.rs and leave the file where it is.