This question already has an answer here:
Why do I need to import a trait to use the methods it defines for a type?
(1 answer)
Closed 2 years ago.
I'm stuck on the first example given in the Rust book, the guessing game. I just cannot find the gen_range method on thread_rng() to generate the number. The only methods that show up are fill_bytes, next_u32, next_u64 and try_fill_bytes, and if I try to write it anyway I get an error saying the method doesn't exist. However, when I tried the random function, which according to the documentation is simply a shortcut for thread_rng().gen(), it works. I've tried other functions, updating and reinstalling everything but it still doesn't work and I really don't know what to do.
Welcome to Stack Overflow. In the future, please try to add more information to your question, including relevant links (which doc are you talking about), source code and error messages. This will make it easier for us to give relevant and useful answers.
I'm assuming you're doing something like this:
use rand::thread_rng;
fn main() {
let x = thread_rng().gen_range(0, 10);
println!("{}", x);
}
Playground
Which gives the following error:
error[E0599]: no method named `gen_range` found for struct `rand::rngs::thread::ThreadRng` in the current scope
--> src/main.rs:4:26
|
4 | let x = thread_rng().gen_range(0, 10);
| ^^^^^^^^^ method not found in `rand::rngs::thread::ThreadRng`
|
::: /playground/.cargo/registry/src/github.com-1ecc6299db9ec823/rand-0.7.3/src/lib.rs:212:8
|
212 | fn gen_range<T: SampleUniform, B1, B2>(&mut self, low: B1, high: B2) -> T
| ---------
| |
| the method is available for `std::boxed::Box<rand::rngs::thread::ThreadRng>` here
| the method is available for `std::sync::Arc<rand::rngs::thread::ThreadRng>` here
| the method is available for `std::rc::Rc<rand::rngs::thread::ThreadRng>` here
|
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
|
1 | use rand::Rng;
|
Note that the Rust compiler is very good in giving suggestions for ways to fix your code. In this case, the last line from the error suggests adding use rand::Rng;, and now it works:
use rand::Rng;
use rand::thread_rng;
fn main() {
let x = thread_rng().gen_range(0, 10);
println!("{}", x);
}
Playground
This is because the gen_range method is not implemented directly on the ThreadRng struct, but instead it is implemented in the general Rng trait, which makes it automatically available for all random number generators. However methods from traits are only available if the trait itself is available, hence the need to import rand::Rng first.
You can try installing the the following version, works for me in this version.
Add this to your Cargo.toml dependencies:
rand = "0.7.3"
Import:
use rand::Rng;
Usage:
rand::thread_rng().gen_range(0, 10);
Related
This question already has answers here:
Lazy sequence generation in Rust
(4 answers)
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
I'm trying to make a function that will return an iterator of all the files in a directory, including all the files in the subdirectories. As I don't know the size of an array that would contain all the files' paths, I thought that it would be easier to have the function return an iterator instead of an array. It's simple enough to do in Python:
def func():
for i in range(0, 100):
yield i
for i in func():
print(i)
But when I try to do something similar in Rust, I get compiler errors and/or compiler panics. Here, I tried some basic syntax that's close to what it is in Python:
fn func() -> Iterator {
for i in 0..100 {
yield i;
}
}
fn main() {
for i in func() {
println!("{}", i);
}
}
But when I compiled it, it caused two errors and a warning:
error[E0658]: yield syntax is experimental
--> src/main.rs:3:9
|
3 | yield i;
| ^^^^^^^
|
= note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
warning: trait objects without an explicit `dyn` are deprecated
--> src/main.rs:1:14
|
1 | fn func() -> Iterator {
| ^^^^^^^^ help: use `dyn`: `dyn Iterator`
|
= note: `#[warn(bare_trait_objects)]` on by default
= warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
= note: for more information, see issue #80165 <https://github.com/rust-lang/rust/issues/80165>
error[E0191]: the value of the associated type `Item` (from trait `Iterator`) must be specified
--> src/main.rs:1:14
|
1 | fn func() -> Iterator {
| ^^^^^^^^ help: specify the associated type: `Iterator<Item = Type>`
Some errors have detailed explanations: E0191, E0658.
For more information about an error, try `rustc --explain E0191`.
warning: `problem` (bin "problem") generated 1 warning
error: could not compile `problem` due to 2 previous errors; 1 warning emitted
I've been playing around with using different return types, like dyn Iterator<Item = i32>, impl Iterator, etc. according to the help in the error messages, and I either get errors, compiler panics, or both. Sorry if this is a stupid question; I've only been working with Rust for around three months. But somehow, it feels like this should be simpler.
So my question: what's the correct syntax for a function returning an iterator generated using the yield keyword? I've looked in the Rust Documentation and The Book, but I've found nothing useful.
An iterator needs to implement Iterator trait.
Rust doesn't use of the yield keyword for generators (for now, Rust 1.57), so you cannot use it.
Direct translation of your code would be:
fn func() -> impl Iterator<Item=u32> {
0..100u32
}
fn main() {
for i in func() {
println!("{}", i);
}
}
The (0..100) is a Range object that implements Iterator
References
Iterator
Generators (Unstable)
Walkdir (solving a similar problem)
I've tried:
#[enum_dispatch(BarTrait, BazTrait)]
pub enum Foo {
VariantZero,
...
}
It seems to ignore any traits after the first, silently.
This causes errors, as in this case the compiler doesn't seem to believe that Foo implements BazTrait.
Update: #kmdreko's code works properly so long as BazTrait is in the same crate as Foo.
When BazTrait is in a different crate, which also uses enum_dispatch, BazTrait is ignored and causes two errors of the form:
error[E0599]: no method named `baz` found for enum `Foo` in the current scope
--> src/main.rs:53:9
|
45 | enum Foo {
| -------- method `baz` not found for this
...
53 | foo.baz();
| ^^^ method not found in `Foo`
|
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `baz`, perhaps you need to implement it:
candidate #1: `mylib::BazTrait`
It is important to note that there is no error at either #[enum_dispatch(BarTrait, BazTrait)] or pub enum Foo {.
The #[enum_dispatch] attribute does not work across crates:
Unfortunately, procedural macros in Rust are limited in a few ways that will make what you're trying to achieve impossible - notably, they are run independently per-crate, so there's no way for information from one crate to affect an implementation in another.
From the author of enum_dispatch in an unrelated issue.
This question already has an answer here:
Why is a trait not implemented for a type that clearly has it implemented?
(1 answer)
Closed 3 years ago.
I'm trying to use the quickcheck crate.
I've implemented Arbitrary for the struct Point {x: u32, y: u32}
impl Arbitrary for Point {
fn arbitrary<G: Gen>(g: &mut G) -> Point {
let x = g.gen::<u32>();
let y = g.gen::<u32>();
Point { x, y }
}
}
and the compiler says:
error[E0599]: no method named `gen` found for type `&mut G` in the current scope
--> src/main.rs:61:23
|
61 | let x = g.gen::<u32>();
| ^^^
|
= note: the method `gen` exists but the following trait bounds were not satisfied:
`&mut G : rand::Rng`
`G : rand::Rng`
= help: items from traits can only be used if the trait is in scope
= note: the following trait is implemented but not in scope, perhaps add a `use` for it:
`use rand::Rng;`
But I do have use rand:Rng; in the test module, and rand as a dev-dependency in my Cargo.toml.
I also have use quickcheck::{quickcheck, Arbitrary, Gen}; in the module.
What am I missing in order to create arbitrary generators?
--- EDIT ---
If you want to run https://gist.github.com/russelldb/49b96ca2e23dfab8a0f03090144735e4 for me it reproduces the issue.
This seems to be an issue with quickcheck. Quickcheck uses rand version 0.6.5, whereas the newest version of rand is 0.7.0.
Because traits of different version aren't compatible rustc gives you this error.
To resolve it, declare rand in the version 0.6.5 as dependecy and it will work.
I have a piece of code like this:
use std::cell::RefCell;
use std::rc::Rc;
struct A(bool);
impl A {
fn get_ref(&self) -> &Rc<RefCell<bool>> {
&Rc::new(RefCell::new(self.0))
}
fn copy_ref(&self) -> &Rc<RefCell<bool>> {
Rc::clone(self.get_ref())
}
}
fn main() {
let a = A(true);
a.copy_ref();
}
and I received warning complaining about the Rc::clone function not getting a reference:
error[E0308]: mismatched types
--> src/main.rs:12:9
|
12 | Rc::clone(self.get_ref())
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected reference, found struct `std::rc::Rc`
|
= note: expected type `&std::rc::Rc<std::cell::RefCell<bool>>`
found type `std::rc::Rc<std::cell::RefCell<bool>>`
I have been working on this all night but I cannot get it to work. The method get_ref is already typed as returning &Rc<RefCell<bool>>, but why would the compiler give the error?
The error is not talking about the argument you put into Arc::clone(), but the whole expression Rc::clone(...) which has a different type (Rc<...>) than the return type of your function (&Rc<...>).
If you were passing a wrong argument to Rc::clone, it would like look this:
--> src/main.rs:13:19
|
13 | Rc::clone(false)
| ^^^^^ expected reference, found bool
|
= note: expected type `&std::rc::Rc<_>`
found type `bool`
So the naive way to fix the type error is to write &Rc::clone(...) instead. Then the last expression of your function has the same type as your function's declared return type. But as you will notice, you will get other errors afterwards.
Let's take a step back to see that your approach is flawed here. For the most important point, please see "Is there any way to return a reference to a variable created in a function?". Spoiler: you really don't want to. So constructs like your get_ref() just don't make sense, as you return a reference to a variable you create inside your function (a variable of type Rc).
In your case the direct solution is probably pretty simple: just remove the reference. Rc<T> is already a pointer/reference type, so there is no need (in general) to have a reference to it.
However, since you are using Rc, you are probably interested in reference counting. So in that case, you probably shouldn't create a new Rc every time the function is called. Otherwise you could end up with a bunch of Rcs with reference count 1, which is not really the point. So instead, your type A should already store an Rc<RefCell<bool>>.
But all I'm doing here is guessing what you actually want to do which is not clear from your question. Maybe you can ask a different question, or add the information to this question, or explain this in the comments.
This question already has answers here:
Why do try!() and ? not compile when used in a function that doesn't return Option or Result?
(4 answers)
Closed 5 years ago.
use std::io;
use std::fs::File;
use std::io::prelude::*;
fn main() {
let mut csv = File::open("Item.csv")?;
}
this is some part of my code, and I've got error:
Compiling eracsv v0.1.0 (file:///C:/Users/jwm/Project/eracsv)
error[E0277]: the trait bound `(): std::ops::Try` is not satisfied
--> src\main.rs:
|
| let mut csv = File::open("Item.csv")?;
| -----------------------
| |
| the `?` operator can only be used in a function that returns `Result` (or another type that implements `std::ops::Try`)
| in this macro invocation
|
= help: the trait `std::ops::Try` is not implemented for `()`
= note: required by `std::ops::Try::from_error`
I have deal with both rustc 1.19 stable and 1.22 nightly and both discharging same error.
but, this is exactly same code as rust doc, isn't it? It is explicitly mentioned that File::open() function returns result .
I am curious why ? operator makes compile error while unwrap() doesn't.
What the error message is actually telling you is you're using the ? operator inside of a function that returns () (this being the main function). The ? operator propagates errors upwards, but it can only do that if the function it's used in actually has a compatible return type that can represent that error.
Or in other words, you can only use it in a function that itself is returning a Result (with a compatible error type). Your main does not return a Result, so you cannot use the ? operator inside of it.
You may also be interested in RFC 1937, which would allow the use of ? in main (by allowing you to declare that main returns a Result).