-
-
Notifications
You must be signed in to change notification settings - Fork 447
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Rng::pick method #198
Add Rng::pick method #198
Conversation
Conflicts: src/libcoretest/iter.rs
Also some tidying up of a bunch of crate attributes
Nothing actually compiles here because `extern crate rand` is apparently still importing the built-in one.
These are not necessary since the crate doesn’t participate in staged_api
Remove extra stability attributes
Cleanup int and uint
Add random keyword to Cargo.toml
Make version bound less strict
Put benchmarks into a black box
This makes documentation work correctly with the new pulldown-cmark Markdown parser (rust-lang/rust#44229).
Fix formatting warnings with commonmark enabled
Seed weak_rng with the current time if OsRng fails
Bump fuschia_zircon to 0.3
I would like to discuss an alternative approach that would result in a breaking change. A better way (imo) of doing this would be to define a trait https://play.rust-lang.org/?gist=49c32c8585108afae51e9642c6872f68&version=nightly RandomKit does something similar via the trait Choose {
type Item;
fn choose<R: Rng>(self, rng: &mut R) -> Option<Self::Item>;
}
impl<T: IntoIterator> Choose for T {
type Item = <T as IntoIterator>::Item;
default fn choose<R: Rng>(self, rng: &mut R) -> Option<T::Item> {
let mut value = None;
for (i, elem) in self.into_iter().enumerate() {
if i == 0 || rng.gen_range(0, i + 1) == 0 {
value = Some(elem);
}
}
value
}
}
impl<'a, T> Choose for &'a [T] {
fn choose<R: Rng>(self, rng: &mut R) -> Option<&'a T> {
if self.is_empty() {
None
} else {
Some(&self[rng.gen_range(0, self.len())])
}
}
}
impl<'a, T> Choose for &'a mut [T] {
fn choose<R: Rng>(self, rng: &mut R) -> Option<&'a mut T> {
if self.is_empty() {
None
} else {
Some(&mut self[rng.gen_range(0, self.len())])
}
}
} The downside is that this relies on specialization, which is currently unstable. This would remove the need for the trait Rng {
...
fn choose<T: Choose>(&mut self, iter: T) -> Option<T::Item> where Self: Sized {
iter.choose()
}
...
} |
See this code |
Acts similarly to choose, except it is generic over all T: IntoIterator.
I think there should be some method that works with any iterator, not just slices. |
I think an iterator implementation could be added. But we shouldn't rely on that alone, because iterators are |
It's a much better alternative to |
Not necessarily. If the length is known in advance, one can do BTW I'm not going to accept a function like this being added into |
I think @dhardy is right that |
@burdges |
Sorry this PR got so suddenly closed. The cause was that we cleaned up the git history (#350) and forced-pushed it to master. Now there was a difference of about 30.000, and I suppose GitHub just gave up... This PR, together with two others, stayed open for so long with little attention because it touches on an area of Rand that needs some design first. That is now slowly getting explored in dhardy#82. |
Acts similarly to choose, except it is generic over all
T: IntoIterator
.