I'm using the ndarray
crate and I have a function that take a reference to Array2
:
fn use_array(array: &Array2<u8>) {
// ...
}
I'm trying to call this function with a view:
image.axis_iter(Axis(2)).for_each(|layer| {
fun(&layer.to_owned());
});
It leads to an error:
|
92 | fun(&layer);
| ^^^^^^ expected struct `ndarray::OwnedRepr`, found struct `ndarray::ViewRepr`
|
error: could not compile `poisson-editing`.
warning: build failed, waiting for other jobs to finish...
= note: expected type `&ndarray::ArrayBase<ndarray::OwnedRepr<u8>, ndarray::dimension::dim::Dim<[usize; 2]>>`
found type `&ndarray::ArrayBase<ndarray::ViewRepr<&u8>, ndarray::dimension::dim::Dim<[usize; 2]>>`
I can solve it by owning the array elements, but then I'm creating an unnecessary copy of the array.
image.axis_iter(Axis(2)).for_each(|layer| {
use_array(&layer.to_owned());
});
Is there a way to avoid the copy here?
Update:
Now I consider it a foolish question. This conversion is not possible because you can not have &T
without creating T
. There is clearly no way to create Array2<u8>
without retaining ownership over the underlying data. I deluded myself into thinking that it should be possible because both ArrayView
and &Array
does not own the data.
No, you can't obtain an &Array2<u8>
, because an &Array2<u8>
is always a reference to a full 2d array, while your layer
contains additional metadata to identify the correct sections of the owned Array2
that are accessible.
However, you could do it the other way around: You can make use_array
take an ArrayView2<u8>
(if it's not part of some external code you depend on) and then change any calls that previously called use_array
with a full 2d array reference to use_array(your_array2.view())
.