There is so much outdated information, it is really hard to find out how to sleep. I'd like something similar to this Java code:
Thread.sleep(4000);
Rust 1.4+
Duration and sleep have returned and are stable!
use std::{thread, time::Duration};
fn main() {
thread::sleep(Duration::from_millis(4000));
}
You could also use Duration::from_secs(4), which might be more obvious in this case.
The solution below for 1.0 will continue to work if you prefer it, due to the nature of semantic versioning.
Rust 1.0+
Duration wasn't made stable in time for 1.0, so there's a new function in town - thread::sleep_ms:
use std::thread;
fn main() {
thread::sleep_ms(4000);
}
Updated answer
This is the updated code for the current Rust version:
use std::time::Duration;
use std::thread::sleep;
fn main() {
sleep(Duration::from_millis(2));
}
Rust play url: http://is.gd/U7Oyip
Old answer pre-1.0
According the pull request https://github.com/rust-lang/rust/pull/23330 the feature that will replace the old std::old_io::timer::sleep is the new std::thread::sleep.
Pull request description on GitHub:
This function is the current replacement for std::old_io::timer which
will soon be deprecated. This function is unstable and has its own
feature gate as it does not yet have an RFC nor has it existed for
very long.
Code example:
#![feature(std_misc, thread_sleep)]
use std::time::Duration;
use std::thread::sleep;
fn main() {
sleep(Duration::milliseconds(2));
}
This uses sleep and Duration, which are currently behind the feature gates of thread_sleep and std_misc, respectively.
Related
I am using rust rocket rocket = { version = "=0.5.0-rc.2", features = ["json"] } as my web server, today I found there is two way to start the rocket, one of the start like this:
#[rocket::main]
async fn main() {
// the rocket start logic
}
the other way look like this:
#[launch]
async fn rocket() -> _ {
// the rocket start logic
}
which one style should I use? which one is better? what should I learn from the two startup style? I am search from google but no one talk about this.
As stated in the documentation, #[rocket::main]
should be used only when the return values of ignite() or launch() are to be inspected
If you use rust-analyzer #[rocket::main] is reliably discovered as the main function which brings the added benefit, that convenient Debug and Run buttons are displayed above the function.
For production it would however be recommended to use the #[launch] attribute.
Recently, I started to learn rust. I'm currently at section 7.4 (bringing paths into scope). Tried hard, but I can't understand the purpose of self::some_sort_of_identifier in rust. Would you please explain what is the difference between use self::module_name::function_name and use module_name::function_name? I tried both and they both worked as expected in the example below:
mod my_mod {
pub fn func() {
print!("I'm here!");
}
}
use my_mod::func;
fn main() {
func();
}
Running this program, as expected, I can see this statement printed into the terminal:
I'm here
And this program here gives me exactly the same results and the rust compiler doesn't complain about anything:
mod my_mod {
pub fn func() {
print!("I'm here!");
}
}
use self::my_mod::func;
fn main() {
func();
}
So, is self:: useless in rust? Why should I even use self::my_mod::my_function(); when I can directly call it like so: my_mod::my_function();.
Are there any cases in which they might defer?
For your use-case, it's mainly a relict from the 2015 rust edition.
In this edition the following code would not compile:
use my_mod::func;
mod my_mod {
use my_mod2::func2;
pub fn func() {
func2();
}
mod my_mod2 {
pub fn func2() {
print!("I'm here!");
}
}
}
fn main() {
func();
}
The compiler complains:
error[E0432]: unresolved import my_mod2
--> src\main.rs:4:9
|
| use my_mod2::func2;
| ^^^^^^^ help: a similar path exists: self::my_mod2
Why did it change? You can see the note about the path and module system changes here.
Rust 2018 simplifies and unifies path handling compared to Rust 2015. In Rust
2015, paths work differently in use declarations than they do
elsewhere. In particular, paths in use declarations would always start
from the crate root, while paths in other code implicitly started from
the current scope. Those differences didn't have any effect in the
top-level module, which meant that everything would seem
straightforward until working on a project large enough to have
submodules.
In Rust 2018, paths in use declarations and in other code work the
same way, both in the top-level module and in any submodule. You can
use a relative path from the current scope, a path starting from an
external crate name, or a path starting with crate, super, or self.
The blog post Anchored and Uniform Paths from the language team also underlines this
The uniformity is a really big advantage, and the specific feature we’re changing -
no longer having to use self:: - is something I know is a big
stumbling block for new users and a big annoyance for advanced users
(I’m always having to edit and recompile because I tried to import
from a submodule without using self).
The keyword itself however is still useful in use statments to refer to the current module in the path itself. Like
use std::io::{self, Read};
being the same as
use std::io;
use std::io::Read;
In rust is there any way to break into the debugger. C# has DebugBreak which when executed simply behaves the same way as though a break point was set there.
Breaking on panic I know how to do and thats not what I am looking for.
Yes, there's ::std::intrinsics::breakpoint (unstable/feature-gated, so only available on nightly Rust):
#![feature(core_intrinsics)]
use ::std::intrinsics::breakpoint;
fn main() {
unsafe { breakpoint() };
}
Where is the recommended place to put use declarations? I couldn't find any decisive answer in the book, in FAQs, mailing lists or online forums. I'm beginning a new project in Rust and I'd prefer to get the right approach right away.
Is one of the two below approaches recommended? Is it only for "aliasing" stuff or does it do more, like initialize a module if it hasn't been used before?
use std::io;
use std::io::Write;
fn some_func() -> () {
[...] // We assume we need std::io here
}
fn some_other_func() -> () {
[...] // We assume we need std::io and std::io::Write here
}
OR
fn some_func() -> () {
use std::io;
[...] // We assume we need std::io here
}
fn some_other_func() -> () {
use std::io;
use std::io::Write;
[...] // We assume we need std::io and std::io::Write here
}
TL;DR: Like almost every other piece of software, it depends on what you are doing. The common style that I have observed (and prefer myself) is to put them at the top of the file and only moving them to narrower scope as needed.
Generally, I recommend starting by placing use statements directly after any extern crate and mod statements, separated by a blank line:
extern crate foo;
extern crate bar;
mod interesting;
use std::collections::HashMap;
use foo::Foo;
use bar::{Quux, moo};
use interesting::something;
// structs, functions, etc.
I base this default on the fact that — most times — an import is used in multiple top-level items. Thus, it makes sense to only import it once.
There are times where imported traits have conflicting methods, and in those cases I scope the import to where it's needed. There are also cases where I'm heavily dealing with a single enum and wish to glob-import it to avoid re-stating the enum's name:
fn foo(e: MyEnum) {
use MyEnum::*;
match e {
One => 1,
Two => 2,
}
}
In certain cases, conflicting use statements indicate that you are attempting too much in a single file and it should be split into separate files and then the use statements are no longer ambiguous.
I am trying to use the flate2 and tar crates to iterate over the entries of a .tar.gz file, but am getting type errors, and I'm not sure why.
Here is my code (and yes, I know I shouldn't use .unwrap() everywhere, this is just POC code):
extern crate flate2; // version 0.2.11
extern crate tar; // version 0.3
use std::io::Read;
use std::fs::File;
use flate2::read::GzDecoder;
use tar::Archive;
fn main() {
let file = File::open("/path/to/tarball.tar.gz").unwrap();
let mut decompressed = GzDecoder::new(file).unwrap();
let unarchived = Archive::new(decompressed);
let entries_iter = unarchived.entries_mut();
}
This gives me the error error: no method named 'entries_mut' found for type 'tar::Archive<flate2::gz::DecoderReader<std::fs::File>>' in the current scope.
GzDecoder::new is returning a DecoderReader<R>, which implements Read as long as R implements Read, which File does, so that should be fine. Archive<O> has different methods depending on what kind of traits O implements, but in this case I am trying to use .entries_mut(), which only requires O to implement Read.
Obviously I am missing something here, could someone help shed some light on this?
Oh man, this is tricky. The published documentation and the code do not match. In tar version 0.3.2, the method is called files_mut:
extern crate flate2; // version 0.2.11
extern crate tar; // version 0.3
use std::fs::File;
use flate2::read::GzDecoder;
use tar::Archive;
fn main() {
let file = File::open("/path/to/tarball.tar.gz").unwrap();
let decompressed = GzDecoder::new(file).unwrap();
let mut unarchived = Archive::new(decompressed);
let _files_iter = unarchived.files_mut();
}
This commit changed the API.
This is a subtle but prevalent problem with self-hosted Rust documentation at the moment (my own crates have the same issue). We build the documentation on every push to the master branch, but people use stable releases. Sometimes these go out of sync.
The best thing you can do is to run cargo doc or cargo doc --open on your local project. This will build a set of documentation for the crates and versions you are using.
Turns out that the published documentation of tar-rs was for a different version than what was on crates.io, so I had to change .entries_mut to .files_mut, and let files = to let mut files =.