【问题标题】:Can I import super:: from a mod that's inside a fn?我可以从 fn 中的 mod 导入 super:: 吗?
【发布时间】:2021-03-22 19:11:55
【问题描述】:

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

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 上下文并直接转到父mod

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

【问题讨论】:

  • 你可以把mod放在fn里面吗?
  • 当您说“不编译”时,包含您遇到的确切错误会有所帮助。

标签: rust


【解决方案1】:

有什么方法可以从mod inner 内部获得对InnerTestStruct 的引用?

不,super 将引用包含的模块,而不是函数范围。据我所知,没有可以命名InnerTestStruct 的路径。

由于您特别提到了宏,Rust API Guidelines 警告这种情况:

项目宏在允许项目的任何地方都起作用

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;
            }
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    • 2019-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多