-
Notifications
You must be signed in to change notification settings - Fork 308
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 Itertools::copied #289
Conversation
I'd vote to leave this out, it is a bit trivial and niche. |
I'd really like to have this as well. I often find myself writing |
That's a case where the Copy bound allows a different, probably-more-efficient implementation, though. That wouldn't be the case with an |
Something worth noting is that |
This can actually be implemented much more simply, though I'm not sure if pub trait IteratorDerefExt: Iterator {
fn deref<'a, T>(self) -> Cloned<Self>
where Self: Sized + Iterator<Item = &'a T>,
T: 'a + Clone + Copy
{
self.cloned()
}
}
impl<T> IteratorDerefExt for T
where T: Iterator {} And yes, I'm in favor of adding this functionality as well. |
Ok this sounds good to me
I have a related problem that still doesn't have a good solution. It's a simple one: Declare a function that takes an iterator of fn sum_the_values<I>(values: I) -> f32
where I: IntoIteratorOf<Item=f32> // New trait?
{
unimplemented!()
} The reason that |
I'm all for it; I'd happily support a patch adding
Here's one solution: fn sum_the_values<B, I>(values: I) -> f32
where
B: std::borrow::Borrow<f32>,
I: IntoIterator<Item = B>,
{
let mut total = 0.0;
for x in values {
total += x.borrow();
}
total
}
fn main() {
println!(
"{} {}",
sum_the_values(std::iter::repeat(1.1).take(5)),
sum_the_values(std::iter::repeat(&1.1).take(5))
);
} |
Neat. I think this (playground) is the expression I'd like, to make it easy to reuse. That is, to hide the Borrow magic behind a new trait and iterator adaptor that makes it simple to use. |
@joshtriplett .cloned() is already in libcore, and I guess there's a chance we can make a proposal for .copied() go through? |
@bluss Seems entirely reasonable. Anyone interested in writing a patch? (Skip the |
I'm interested in writing a patch. |
Add unstable Iterator::copied() Initially suggested at rust-itertools/itertools#289, however the maintainers of itertools suggested this may be better of in a standard library. The intent of `copied` is to avoid accidentally cloning iterator elements after doing a code refactoring which causes a structure to be no longer `Copy`. This is a relatively common pattern, as it can be seen by calling `rg --pcre2 '[.]map[(][|](?:(\w+)[|] [*]\1|&(\w+)[|] \2)[)]'` on Rust main repository. Additionally, many uses of `cloned` actually want to simply `Copy`, and changing something to be no longer copyable may introduce unnoticeable performance penalty. Also, this makes sense because the standard library includes `[T].copy_from_slice` to pair with `[T].clone_from_slice`. This also adds `Option::copied`, because it makes sense to pair it with `Iterator::copied`. I don't think this feature is particularly important, but it makes sense to update `Option` along with `Iterator` for consistency.
Given that nightly has this available now, I don't think itertools should add it. Given that, I think this can be closed. |
Add unstable Iterator::copied() Initially suggested at rust-itertools/itertools#289, however the maintainers of itertools suggested this may be better of in a standard library. The intent of `copied` is to avoid accidentally cloning iterator elements after doing a code refactoring which causes a structure to be no longer `Copy`. This is a relatively common pattern, as it can be seen by calling `rg --pcre2 '[.]map[(][|](?:(\w+)[|] [*]\1|&(\w+)[|] \2)[)]'` on Rust main repository. Additionally, many uses of `cloned` actually want to simply `Copy`, and changing something to be no longer copyable may introduce unnoticeable performance penalty. Also, this makes sense because the standard library includes `[T].copy_from_slice` to pair with `[T].clone_from_slice`. This also adds `Option::copied`, because it makes sense to pair it with `Iterator::copied`. I don't think this feature is particularly important, but it makes sense to update `Option` along with `Iterator` for consistency.
This is to pair with
cloned
. There are other pairs like that in Rust, likecopy_from_slice
andclone_from_slice
. This allows to avoid accidentally callingclone
while usingcloned
method, by allowing to use a specialization that only acceptsCopy
types.