首页 > 解决方案 > 我可以从 fn 中的 mod 导入 super:: 吗?

问题描述

我意识到这是一件非常奇怪的事情,但我正在编写一个宏,我希望它可以在尽可能多的地方使用。采取以下代码

mod outer {

    struct OuterTestStruct {}
    
    fn do_thing() {

        struct InnerTestStruct {}
        
        mod inner {
            use super::OuterTestStruct;
            use super::InnerTestStruct;
        }
    }
    
}

use super::InnerTestStruct由于该行,这无法编译。但是这use super::OuterTestStruct条线工作正常,所以我在这里的假设是super跳过fn上下文并直接进入 parent mod

有什么办法可以InnerTestStruct从内部获得参考mod inner吗?尤其是在事先不知道任何上下文的情况下(即想象内部的宏调用fn do_thing(),它不会知道它在 fn 内部)

标签: rust

解决方案


有什么办法可以InnerTestStruct从内部获得参考mod inner吗?

不,super将指的是包含模块,而不是功能范围。InnerTestStruct据我所知,没有可以命名的路径。

由于您特别提到了宏,因此Rust API 指南对这种确切情况提出了警告:

项目宏在允许项目的任何地方工作

Rust 允许将项目放置在模块级别或像函数一样的更紧凑的范围内。物品宏在所有这些地方都应该和普通物品一样好用。测试套件应至少在模块范围和函数范围内包含对宏的调用。

作为一个简单的例子,这个宏在模块范围内工作得很好,但在函数范围内却失败了。

macro_rules! broken {
    ($m:ident :: $t:ident) => {
        pub struct $t;
        pub mod $m {
            pub use super::$t;
        }
    } }

broken!(m::T); // okay, expands to T and m::T

fn g() {
    broken!(m::U); // fails to compile, super::U refers to the containing module not g
}

我知道的唯一解决方法是引入另一个模块:

mod outer {
    struct OuterTestStruct {}

    fn do_thing() {
        mod middle { // <----------------
            struct InnerTestStruct {}

            mod inner {
                use super::super::OuterTestStruct;
                use super::InnerTestStruct;
            }
        }
    }
}

推荐阅读