-
Notifications
You must be signed in to change notification settings - Fork 544
Use &[T] instead of &Vec<T> where possible #454
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
Conversation
exercises/custom-set/example.rs
Outdated
.iter() | ||
.cloned() | ||
.filter(|c| other.contains(c)) | ||
.collect::<Vec<_>>()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if it can be done without the collect. First attempt, note that simply remove it completely will result in:
error[E0308]: mismatched types
--> src/lib.rs:45:24
|
45 | CustomSet::new(&self.collection
| ________________________^
46 | | .iter()
47 | | .cloned()
48 | | .filter(|c| other.contains(c))
| |__________________________________________________________^ expected slice, found struct `std::iter::Filter`
|
= note: expected type `&[T]`
found type `&std::iter::Filter<std::iter::Cloned<std::slice::Iter<'_, T>>, [closure@src/lib.rs:48:37: 48:58 other:_]>`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Vec::retain
exists where it only keeps the items which meet the predicate. It does operate on &mut Vec
though so the Vec
will need to be cloned.
fn intersection(&self, other: &Self) -> CustomSet<T> {
let mut collection = self.collection.clone();
collection.retain(other.contains)
CustomSet::new(collection)
}
As well as that, there seems to be no reason for |c| other.contains(c)
as it is equivalent to other.contains
as far as I can tell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think https://stackoverflow.com/questions/37801375/filter-a-slice-into-a-vector may give some hints as how to answer my question
Vec::retain
[...] does operate on&mut Vec
Then I think it will not serve the goal (not having to create a temporary variable)
I admit I did not state my goal very precisely, therefore this is my fault that it did not serve the goal.
As well as that, there seems to be no reason for
|c| other.contains(c)
as it is equivalent toother.contains
as far as I can tell.
True story, but I'm not allowed to make that change in this PR since it's out of scope. Good change to put in another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what I want is https://stackoverflow.com/questions/34969902/how-to-write-a-rust-function-that-takes-an-iterator
fn do_things(foos: &[usize]) {
println!("Thanks for giving me {:?}", foos);
}
fn do_more_things<'a, I>(foos: I) where I: IntoIterator<Item = &'a usize> {
for foo in foos {
println!("Thanks for giving me more {}", foo);
}
}
fn main() {
let foos = [5, 10];
// Works. Great!
do_things(&foos);
// Nice, both of these work!
do_more_things(&foos);
do_more_things(foos.iter());
let even_foos: Vec<_> = foos.iter().filter(|f| *f % 2 == 0).cloned().collect();
// Works too. All right.
do_things(&even_foos);
do_more_things(&even_foos);
// Shall we do it without collect() ?
//let even_foos2 = foos.iter().filter(|f| *f % 2 == 0).cloned();
// I don't think there's a way to make this one work.
//do_things(&even_foos2);
// This is fine though.
do_more_things(foos.iter().filter(|f| *f % 2 == 0));
}
Hmm, maybe I misunderstood. I am looking in #400 (comment)
In that case, I'm making a few changes. |
Actually, I think I'll stop to ask questions before making changes. The question I have right now is: Clippy for sure asks for any If we have something on two separate lines:
Should we take a similar tack of removing If we do, assuming we still keep it on separate lines (perhaps the line would be too long if moving everything to one line), which form shall we change it to? Choice 1:
Choice 2:
|
There was a key pair of follow-up comments in #400, which are now hidden by default: 1, 2. I'd given the submitter bad advice earlier in that thread.
If it is reasonable for the list to ever need to grow, it should be a If we implement slice literals, I prefer your choice 1. The reasoning is that slices are immutable. Under choice 1, students who want to attempt to mutate them will need to write more: |
Clippy suggested: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. https://rust-lang-nursery.github.io/rust-clippy/master/index.html#ptr_arg
The tests create a vector and immediately take a reference to it, doing nothing else to the vector. If this were on a single line, Clippy would suggest: useless use of `vec!` https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_vec Since these vectors are constructed strictly to express the expected output and are never expected to grow/shrink, it is reasonable to simply use a slice.
Clippy suggested: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. https://rust-lang-nursery.github.io/rust-clippy/master/index.html#ptr_arg
The tests create a vector and immediately take a reference to it, doing nothing else to the vector. If this were on a single line, Clippy would suggest: useless use of `vec!` https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_vec Since these vectors are constructed strictly to express the input dominoes and are never expected to grow/shrink, it is reasonable to simply use a slice.
Clippy suggested: this argument is passed by value, but not consumed in the function body https://rust-lang-nursery.github.io/rust-clippy/master/index.html#needless_pass_by_value
Clippy suggested: this argument is passed by value, but not consumed in the function body https://rust-lang-nursery.github.io/rust-clippy/master/index.html#needless_pass_by_value
Clippy suggested: useless use of `vec!` https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_vec
Clippy suggested: useless use of `vec!` https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_vec
Clippy suggested: useless use of `vec!` https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_vec
Clippy does not give a suggestion for this one, but this makes sense to do because the set of tests we construct will not need to change (they're all eight input possibilities), so we do not need to use a Vec.
OK. In that case I've confirmed that the commits in this PR which make the relevant change from |
I'm moving the |
Clippy suggested: writing `&Vec<_>` instead of `&[_]` involves one more reference and cannot be used with non-Vec-based slices. https://rust-lang-nursery.github.io/rust-clippy/master/index.html#ptr_arg
The tests create a vector and immediately take a reference to it, doing nothing else to the vector. If this were on a single line, Clippy would suggest: useless use of `vec!` https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_vec Since these vectors are constructed strictly to express the input lines and are never expected to grow/shrink, it is reasonable to simply use a slice.
Clippy suggested: useless use of `vec!` https://rust-lang-nursery.github.io/rust-clippy/master/index.html#useless_vec
I will have to rebase #434 after merging this, but that's fine, I was prepared to do so! I think these changes are uncontroversial so with the Approval as assurance that I didn't make an obvious mistake somewhere it's time to merge it. |
I believe this covers the following Clippy lints:
&Vec<_>
instead of&[_]
involves one more reference and cannot be used with non-Vec-based slices.Vec<T>
to&[T]
in one commit; the resulting code compiles. Then a second commit was additionally made to change uses ofvec!
into slices, which is not necessitated by the first commit by the commit but is enabled by it.Vec<T>
to&[T]
and the usages were changed fromvec!
to slices in one commit, since both changes need to happen together for the tests to compile.vec!
vec!
were changed to slices.