-
Notifications
You must be signed in to change notification settings - Fork 10
Expose the array
field (or add as_array(&self) -> &K::Array
)
#26
Comments
I can agree that having access to the underlying array by ref is useful (in particular you can eliminate runtime bounds checking in some cases without |
It helps exactly for bounds checking. For example, we can take two enum maps FWIW this kind of zip as well as some other operations is what we're looking to do, we have a lot of same-key |
I guess the confusion came from:
I wanted to say that we'll be able to iterate over values ignoring the keys: of course they'll be references to the values as you mention. We don't want a slice as that removes the array length which is the main thing we care about as we want to manipulate multiple |
If the maps you're zipping together all use the same enum for keys, you can try creating iterator types that go through each variant in turn; then your zipping becomes |
You missed the "ignoring the keys" part: I don't want to see and use Having access to the arrays by reference allows us to uniformly access multiple Your proposed solution requires |
Heck, even if you do want a key, multiple operations can be more efficient. You can have some |
Where I would find this helpful is that right now, as far as I can tell, there's no way to map over an Here's my use-case: I have something like #[derive(Debug, Default)]
struct Foo { ... };
#[derive(Debug)]
struct View<'a> {
foo: &'a Foo,
}
impl Foo {
pub fn view(&self) -> View<'_> {
View { foo: self }
}
}
let foo_map: EnumMap<Key, Foo> = EnumMap::default();
let view_map: EnumMap<Key, View> = /* ? */; I can't say let view_map = foo_map.clone().map(Foo::view); because (a) that requires let view_map: EnumMap<_, _> = foo_map
.iter()
.map(|(id, foo)| (id, foo.view()))
.collect(); because let view_map = enum_map! {
key => foo_map[key].view(),
} which works, but why does the macro get to use magic that I can't replicate using simple iterators? 😄 (I know, it forces there to be a mapping for every key, so there's no chance of an entry being left uninitialized.) Also, it wouldn't help if I needed to anything more complicated than To do this today with just iterators, the only solution I could find is, let view_array: <Key as EnumArray<_>>::Array = foo_map
.values()
.map(Foo::view)
.collect<Vec<_>>() // Can't collect directly into an array.
.try_into()
.expect("EnumMap gave us a slice with a different length");
let view_map = EnumMap::from_array(view_array); which requires a heap allocation and unwrapping a But, if I had let view_array = foo_map.as_array().each_ref().map(Foo::view);
let view_map = EnumMap::from_array(view_array); Since the array is bounded, I could manipulate it safely and give it back to Having let view_map: EnumMap<_, _> = foo_map.as_array().each_ref().map(Foo::view).into(); Of course, another solution would be to have |
An alternative would be to simply expose the `array` field as `pub`: whatever works. I went with this as it allows adding simple docs at the same time. Fixes KamilaBorowska#26.
An alternative would be to simply expose the `array` field as `pub`: whatever works. I went with this as it allows adding simple docs at the same time. Fixes KamilaBorowska#26.
Very exciting! |
It's currently possible to:
EnumMap
fromK::Array
withfrom_array
EnumMap
toK::Array
withinto_array
as_slice
andas_mut_slice
But it's currently not possible to get a reference to
K::Array
directly, mutable or not. This is useful if the contents aren'tClone
-able but we still want to iterate over the values directly (without concerning ourselves with the keys).At this point, it seems that just exposing the
array
field ofEnumMap
as public should be fair game: we already have setter/getter and hiding it just makes it inconvenient.The text was updated successfully, but these errors were encountered: