Hacker News new | past | comments | ask | show | jobs | submit login

The Rust module system is a little bit weird. As far as I can tell, this is the result of two things:

- 'use' statements are relative to the root of the crate, not the current module. To work around this, you can write 'use self::name' or 'use super::name' for relative imports. Annoying but no big deal.

- If you import a symbol into module 'a', it doesn't also get added to 'a::b'. I don't know why I keep expecting this.

Once I learned these two things, Rust imports were easy.

I'm not sure I agree with withoutboats' proposals. His chnages would make several obvious things work the first time, but at the expense of taking a simple, easy to explain rule and replacing it with something implicit and mysterious.

The bigger Rust learning curve issue is making friends with the borrow checker. I like the borrow checker. It has my back, even when I'm trying to write fast code that would be recklessly abusive of pointers in C. But I can't deny that it took me a week or two to make friends with the borrow checker.




'use' statements are relative to the root of the crate, not the current module. To work around this, you can write 'use self::name' or 'use super::name' for relative imports. Annoying but no big deal.

I'm writing an application. Inside main.rs I can write

  extern crate foo;
  use foo::Bar;
If I create a module and use the same crate, I need to write:

  extern crate foo;
  use self::foo::Bar;
This always surprises me and I never found anything explicit written on the Book. To me, it looks like a nice papercut to fix.


Why do you have an `extern crate foo` line inside a module that I'm assuming (because of the `self`) is part of crate foo? You shouldn't need to `extern crate` inside that crate itself.

One thing that might be confusing is that `main.rs` is the entry file of binary crates, while `lib.rs` is the entry file of library crates, and a project can contain both a binary and a library crate. The binary crate then does need to `extern crate` the library crate.

We've been working on a new version of the book, if you have time, I'd love if you would take a look at the new chapter on modules [1] and file PRs or issues on the repo [2] if it's still confusing or leaving you with unresolved questions!

[1] - http://rust-lang.github.io/book/ch07-00-modules.html [2] - https://github.com/rust-lang/book


I keep tripping over that as well. It makes the crate root feel special compared to other modules, and that's annoying because most people learning the language probably spend a lot of time in the crate root, writing simple toy programs.


What if I really do want the 'foo' crate to be inside the sub-module? If you want it in the crate root, you should put it in the crate root.


Sorry, I don't really grasp your comment. Maybe I can clarify what I'm trying to do.

My typical use case is importing definitions, for example an error type or enum from the crate, let's say something from tokio_core.

I'd like to use this enum both in main and in my module; from my (limited) experience, you need to extern crate tokio_core both in main and the module, then use the definition. In this case the syntax is different for somewhat obscure reasons.


Hmmmm, do you mean that you don't want to put all your `extern crate` statements in the root of your library? If you do that, you don't have to have the `self` when you use items from the crate within your modules. I've never wanted to put my `extern crate` statements within a module rather than the library crate root; can you elaborate on why you want to do that?


Hm, I'm still confused about what you're trying to do :-/ If you're trying to use something from tokio_core in your own crate, in neither place will `use self` do that, like you had in your first example... it would be `use tokio_core::foo::Bar`... and the `self` was the only difference between the binary and library, so I'm not sure what the paper cut is exactly.


Basically I start hacking on a project, then when finally something is working, I want to split it into a separate "something". Coming from the C++ world, I'd create a new cpp/h couple, maybe in its own subdir. I understand that the equivalent in Rust is creating a module.

I made a simple example with just two files: (In the meanwhile I realized that my first example was wrong :) https://github.com/lucaotta/rust_modules

Let's say that after my refactor, I've "moved" the crate import into the module since "logically" it belongs there. In this case the compilation fails if I don't use self::. But previously it was working in main.rs! And I have no idea why...


This is the "use starts at the crate root" thing. If you move the "extern crate", then the place it ends up in the module hierarchy is different, and so it breaks.

I always leave "extern crate" in the crate root; then it all Just Works.


The convention is to always keep `extern crate`s in the crate root. `use`s get moved around, but `extern crate`s stay put. Think of `extern crate` as if it were a crate-internal `pub use` (because that's kind of what it is!).


"I'm not sure I agree with withoitboats' proposals. His chnages would make several obvious things work the first time, but at the expense of taking a simple, easy to explain rule and replacing it with something implicit and mysterious."

Which is ironic, considering the premise is that the module system is "too confusing". Having never used Rust, the current rules - as explained by the author himself - seemed straightforward. For the proposed new rules, I'm confronted with two long paragraphs.

I didn't bother to read them. If the intent is to make the system less confusing, there should be a way to explain the new rules as tersely as the old ones.


A blog post proposal to the Rust community with a rough set of ideas need not fixate on itself being super easy to understand. That's for the RfC to do (we require a "how do we teach this" section on RfCs)

That being said, I do feel that the union of a confusing and simple system can often be a more confusing system so I'm wary of this proposal reducing complexity.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: