简体   繁体   中英

Rust ndarray mismatched types

I'm trying to get an Array3 from an image using ndarray_image:

pub fn from_png(path: &str) -> Result<Self, &str> {
        return match ndarray_image::open_image(path, Colors::Rgba) {
            Ok(data) => { ;
                let size = Size {
                        x: data.shape()[0],
                        y: data.shape()[1]
                    };
                Ok( Self { data, size } )
            }
            Err(_) => {
                Err("Unable to open image!")
            }
        }
    }

Self.data type is Array3 and open_image returns an Array3. It is so strange, but in error types also same:

error[E0308]: mismatched types
   |
   |                 Ok( Self { data, size } )
   |                            ^^^^ expected struct `ArrayBase`, found struct `ndarray::ArrayBase`
   |
   = note: expected struct `ArrayBase<OwnedRepr<u8>, Dim<[usize; 3]>>`
              found struct `ndarray::ArrayBase<ndarray::data_repr::OwnedRepr<u8>, ndarray::dimension::dim::Dim<[usize; 3]>>`
   = note: perhaps two different versions of crate `ndarray` are being used?

About versions: I use version "0" for all ndarray-* crates.

Dependencies in Cargo.toml:

[dependencies]
bytes = "1.1.0"
font-kit = "0.10.1"
pathfinder_geometry = "0.5.1"
image = "0.23.14"
rayon = "1.5.1"
ndarray = { version="0", features=["rayon", "serde"]}
serde = "1.0.133"
serde_json = "1.0.74"
ndarray-stats = "0"
ndarray-image = "0"

Here's what I get grepping for ndarray in whole your dependency tree:

$ cargo tree | grep ndarray
├── ndarray v0.15.4
├── ndarray-image v0.3.0
│   └── ndarray v0.14.0
├── ndarray-stats v0.5.0
│   ├── ndarray v0.15.4 (*)

As you can see, there are indeed two incompatible versions of ndarray - one pulled in by ndarray-image and another by ndarray-stats .

The reason for this is the fact that Cargo doesn't try to resolve immediate dependencies version based on their dependencies. All it does know is that you've requested some 0.xy version for each ndarray-* , so it picks the latest one - and they happen to be unusable together.


To make this work, you have to downgrade your ndarray to the lowest version available for other dependencies, ie 0.14 .

For direct dependency, this is as easy as just requiring the desired version explicitly.
For ndarray-stats , we have to look through the previous versions looking for their dependencies; happily, this is explicitly documented on the crate page : the version we're looking for is0.4.0 .
It's also advisable to pin the minor version for ndarray-image too, so that the breakage won't appear again unexpectedly on its update.

Now, the corresponding part of Cargo.toml looks like this:

ndarray = { version="0.14", features=["rayon", "serde"]}
ndarray-stats = "0.4"
ndarray-image = "0.3"

And the output of cargo tree is like this:

$ cargo tree | grep ndarray
├── ndarray v0.14.0
├── ndarray-image v0.3.0
│   └── ndarray v0.14.0 (*)
├── ndarray-stats v0.4.0
│   ├── ndarray v0.14.0 (*)

I can't check your code as-is, since it's not a MRE , but after these changes it should compile - save for possibly now-missing APIs, if you've used something from ndarray v0.15 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM