是否可以将impl拆分为不同的模块?

时间:2014-08-09 14:47:21

标签: rust

我正在尝试将impl拆分为不同的模块。 子impl块中的项应该可以由父impl访问,但不能由实现的struct / enum的用户公开访问。

这是我的尝试:

mod foo {
    pub struct Foo {
        field: String
    }

    impl Foo {
        pub fn new() -> Foo {
            Foo { field: "Joe".to_string() }
        }
        pub fn pubfn(&self) {
            self.my_impl();
        }
    }

    // Ideally, this should be in a separate file
    mod foo_impl_details {
        impl super::Foo {
            // If I make this `pub`, it will be publicly visible to
            // users of `Foo`, not just the impl block in `super`
            fn my_impl(&self) {
                println!("{} reporting for duty!", self.field);
            }
        }
    }
}

fn main() {
    let foo = foo::Foo::new();
    foo.pubfn();
}

这会导致编译错误:

<anon>:11:13: 11:27 error: method `my_impl` is private
<anon>:11             self.my_impl();
                      ^~~~~~~~~~~~~~

如果我使用my_impl标记pub方法,它不仅可以公开访问父模块的impl块,还可以公开访问foo::Foo块的外部用户{1}},这不是我想要的。

3 个答案:

答案 0 :(得分:2)

这看起来有点像预期的行为:my_impl方法是私有的,因此仅在声明它的模块中可见。另一方面,奇怪的是pub版本随处可见,尽管foo_impl_details是私有模块。我就此提出了#16398

您可以将模块(以及文件,因为mod foo { ... }mod foo;foo.rsfoo/mod.rs中的代码相同)分开,同时使用独立式保持隐私功能,例如

mod foo {
    pub struct Foo {
        field: String
    }

    impl Foo {
        pub fn new() -> Foo {
            Foo { field: "Joe".to_string() }
        }
        pub fn pubfn(&self) {
            foo_impl_details::my_impl(self);
        }
    }

    mod foo_impl_details {
        fn my_impl(x: &super::Foo) {
            println!("{} reporting for duty!", x.field);
        }
    }
}

除了调用语法之外,独立函数和方法之间没有区别。

此外,编写与特征声明不相邻的非特征impl存在各种问题,因此这种行为可能不是设计的,例如。

因此an RFC暂时(暂时)删除此功能。

答案 1 :(得分:1)

这很有效。

mod foo {
    use self::extension::Extension;

    pub struct Foo {
        field: String
    }

    impl Foo {
        pub fn new() -> Foo {
            Foo { field: "Joe".to_string() }
        }
        pub fn pubfn(&self) {
            self.my_impl();
        }
    }

    mod extension {
        pub trait Extension {
            fn my_impl(&self);
        }
        impl Extension for super::Foo {
            fn my_impl(&self) {
                println!("{} reporting for duty!", self.field);
            }
        }
    }
}

答案 2 :(得分:1)

普通impl阻止?嗯,这是目前非常错误的东西,虽然你可以稍微解决这些错误may well be removed。我强烈建议不要首先尝试这样做。

至于特质的实现,它们可以放在箱子里的任何地方。