首页 > 解决方案 > 带有通配符使用声明的 Rust 子模块行为

问题描述

我试图了解使用通配符路径时(子)模块导入是如何工作的。我能想到的最简单的演示如下,其中两个模块,或者可能是两个 crate,共享相同的模块结构。

pub mod primary {
    pub mod a {
        pub mod b {
            pub struct A(pub i32);
        }
    }
}

pub mod import {
    pub use crate::primary::*;
    // Compiles and executes fine with this commented out, but fails with
    // "error[E0433]: failed to resolve: could not find `b` in `a`"
    // otherwise. The error refers to the usage in the assert_eq macro
    // pub mod a {}
}

fn main() {
    assert_eq!(import::a::b::A(42).0, 42);
}

我的一般想法是,由于第一种情况,在pub mod a {}注释掉的情况下,通配符应该将通配符拾取的所有子模块扩展为它正在扩展的路径中的子模块。不是这样吗?如果是这样,思考的适当方式是什么?

使用声明对此没有太多详细信息。

标签: rust

解决方案


use使用 a*导入所有名称,除了那些与当前模块中已经存在的名称冲突的名称。

比较:

pub mod primary {
    pub fn f() {
        println!("p::f");
    }
}

pub mod import {
    pub use crate::primary::*;
}

fn main() {
    import::f();
}

打印p::f到_

pub mod primary {
    pub fn f() {
        println!("p::f");
    }
}

pub mod import {
    pub use crate::primary::*;

    pub fn f() {
        println!("import::f");
    }
}

fn main() {
    import::f();
}

打印import::f。_


这对于函数和常量来说似乎很明显(否则它会变得*非常有限,使得上游库不可能在不冒破坏下游用户的情况下添加任何项目),但对于模块来说似乎更加混乱。您必须记住,您不能多次定义一个模块(即“重新打开”一个模块)。以下是非法的:

pub mod primary {
    pub mod a {}
    pub mod a {}
}

失败了

error[E0428]: the name `a` is defined multiple times
 --> src/lib.rs:3:5
  |
2 |     pub mod a {}
  |     --------- previous definition of the module `a` here
3 |     pub mod a {}
  |     ^^^^^^^^^ `a` redefined here
  |
  = note: `a` must be defined only once in the type namespace of this module

您可以通过再添加一个级别来解决这种特殊情况:

pub mod primary {
    pub mod a {
        pub mod b {
            pub struct A(pub i32);
        }
    }
}

pub mod import {
    pub mod a {
        pub use crate::primary::a::*;
    }
}

fn main() {
    assert_eq!(import::a::b::A(42).0, 42);
}

推荐阅读