-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Refactor collections::list #12348
Refactor collections::list #12348
Conversation
@alexcrichton r? :-) |
It seems to me any/find/etc. should be just removed, since one can use |
@@ -10,170 +10,164 @@ | |||
|
|||
//! A standard, garbage-collected linked list. | |||
|
|||
|
|||
pub type BoxedList<T> = @List<T>; |
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'm not sure that this is the right use of a typedef. @List
is smaller and more concise to write, and it is also more clear about how the list is built.
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.
The intention here is to reduce usage of @list as I'm planning to replace it with Rc - do you believe it is still worth?
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 don't think an alias is necessary here in either case.
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.
Right, removing then.
So here goes a rough list of things fixed since first attempt:
|
@alexcrichton, about having On |
} | ||
}; | ||
} | ||
} |
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.
Hm, I'm not sure how feasible this list will be if it require that its elements be clone-able. This also means that every time you get the length of the list you clone every object in the list!
You're going to want to return &'a T
from this iterator so you can remove the Clone
bound, which may mean that you need to store &'a List
instead of @List
like I had originally hoped.
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.
Replacing Option<T>
with Option<&'a T>
on next()
gives the following compilation error because of different signatures between Iterator's trait and this:
/Users/bruno.d/Work/rust/src/libcollections/list.rs:32:5: 40:6 error: method `next` has an incompatible type: expected type parameter but found &-ptr
/Users/bruno.d/Work/rust/src/libcollections/list.rs:32 fn next(&'a mut self) -> Option<&'a T> {
/Users/bruno.d/Work/rust/src/libcollections/list.rs:33 match *(self.current) {
/Users/bruno.d/Work/rust/src/libcollections/list.rs:34 Cons(ref value, ref next) => {
/Users/bruno.d/Work/rust/src/libcollections/list.rs:35 self.current = *next;
/Users/bruno.d/Work/rust/src/libcollections/list.rs:36 Some(value)
/Users/bruno.d/Work/rust/src/libcollections/list.rs:37 },
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.
It does indeed, you'll need to add a lifetime parameter to the struct:
pub struct Items<'a, T> { next: &'a List<T> }
iter should be named items, I think
|
Fixes since last iteration:
|
@liigo the iterator struct is called |
The build error seems unrelated to this PR:
|
tl | ||
} | ||
Nil => return false | ||
impl<'a, T> List<T> { |
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.
Instead of putting the lifetime parameter at the top of the impl
block, you can place it on the individual functions below as fn foo<'a>(&'a self) -> ...
.
You can then merge this impl block with the one below.
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.
Ack :-)
This is looking great, nice work! Before committing, this'll need to squash some of the commits together, but that can wait until review is done. |
The Nil/Cons construction seems to duplicate Option. What about defining List equivalently as:
Or ideally with this more natural representation:
(or using a tuple struct instead of with head/tail fields) Note that also the current representation, equivalent to the first snippet, is very weird, since it starts the list with an inline element, terminates with a ~Nil. This means that it passes data by value, requiring an explicit copy to prepend an element to the list due to the need to box the Cons and requires an explicit tag for the Nil vs Cons discriminator rather than being able to use the Option null pointer optimization. It's definitely not how one would naturally implement a singly linked list in C, for example, while the second code snippet in this comment is the natural representation where an empty list is just a null pointer. |
This definition should also be possible, for the second snippet above (and I remember mentioning it a couple times in the past, on IRC): struct Cons<T> {
head: T,
tail: List<T>
}
type List<T> = Option<~Cons<T>>; |
@alexcrichton, @bill-myers, @eddyb: I want to postpone modifying how |
Fixes since last iteration:
|
ret | ||
if isr_br == br { region = Some(isr_r); break; } | ||
}; | ||
region.unwrap() | ||
} |
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.
This change seems unrelated to the list changes?
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.
Initially I've modified the code to replace list::each()
with a for isr in self.iter()
statement. But then I ended up with a refactor to simplify get_and_find_region::{get,find}()
code. I can separate this if it seems necessary.
This looks good to me, I don't think it needs 21 commits, but with some squashings I'll r+ |
Ok, so I squashed a few commits and the # of commits is now down to 18. |
…ry, r=alexcrichton This PR includes: - Create an iterator for ```List<T>``` called ```Items<T>```; - Move all list operations inside ```List<T>``` impl; - Removed functions that are already provided by ```Iterator``` trait; - Refactor on ```len()``` and ```is_empty``` using ```Container``` trait; - Bunch of minor fixes; A replacement for using @ is intended, but still in discussion. Closes #12344.
Remove `clippy_utils::get_parent_node` Since it's forwarding to a single method it seems reasonable to use that one directly instead changelog: none
This PR includes:
List<T>
calledItems<T>
;List<T>
impl;Iterator
trait;len()
andis_empty
usingContainer
trait;A replacement for using @ is intended, but still in discussion.
Closes #12344.