Почему мне нужно использовать дополнительный префикс `::` для доступа к импортированной структуре?

В моем lib.rs Я хотел сделать use std::fs::File,

Вот пример кода:

use std::fs::File;
use std::io::Read;

impl Css { 
    pub fn save_result_to_file(file_to_save: String) {
        println!("Saving output to {}", file_to_save);
        let mut f = File::open(file_to_save).expect("Unable to open file");
        // let mut f = ::File::open(file_to_save).expect("Unable to open file"); -> Works
    }
}

Без присутствия :: до File Я получаю ошибку компилятора:

|  let mut f = File::open(file_to_save).expect("Unable to open file");
|                         ^^^^^^^^^^ Use of undeclared type or module `File`

Мой вопрос - это :: Приставка всегда нужна? Я уверен, что нет, но не могу понять, как это сделать.

1 ответ

Решение

Вы можете думать о :: разделитель пути модуля так же, как / в пути к файлу, и так же, как ведущий / означает корневой каталог, ведущий :: ссылается на корневой модуль вашего приложения.

Когда вы импортируете элемент с use затем имя этого элемента фактически становится (закрытым по умолчанию) членом этого модуля, и на него можно ссылаться из других модулей, используя абсолютные или относительные пути. Так что тот факт, что у вас возникла эта проблема, говорит мне, что ваш use операторы находятся в вашем корневом модуле, в то время как другой код находится в дочернем модуле. Вот почему вышеприведенные комментаторы не смогли воспроизвести его из кода, который вы действительно разместили.

У вас есть некоторая структура модуля, как это:

use std::fs::File;
use std::io::Read;

mod Foo {
    struct Css {}
    impl Css { 
        pub fn save_result_to_file(file_to_save: String) {
            println!("Saving output to {}", file_to_save);
            let mut f = ::File::open(file_to_save).expect("Unable to open file");
        }
    }
}

Ведущий :: необходимо, потому что File был импортирован в корневой модуль, но вы используете его в дочернем модуле. Если вы перенесете импорт в тот модуль, который содержит ваш код, он будет работать без :::

mod Foo {
    use std::fs::File;
    use std::io::Read;

    struct Css {}
    impl Css { 
        pub fn save_result_to_file(file_to_save: String) {
            println!("Saving output to {}", file_to_save);
            let mut f = File::open(file_to_save).expect("Unable to open file");
        }
    }
}
Другие вопросы по тегам