我正在try 基于正在为其编译应用程序的设备来更改应用程序的图标(我正在使用image crate加载).不幸的是,在try 运行代码时:

    let (icon_rgba, icon_width, icon_height) = {
        let icon = if cfg!(target_os = "macos") {
            include_bytes!("../assets/icon-macos.png")
        } else {
            include_bytes!("../assets/icon.png")
        };
        let image = image::load_from_memory(icon)
            .expect("Failed to open icon path")
            .into_rgba8();
        let (width, height) = image.dimensions();
        let rgba = image.into_raw();
        (rgba, width, height)
    };

我得到以下错误:

error[E0308]: `if` and `else` have incompatible types
 --> src/main.rs:6:13
  |
3 |           let icon = if cfg!(target_os = "macos") {
  |  ____________________-
4 | |             include_bytes!("../assets/icon-macos.png")
  | |             ------------------------------- expected because of this
5 | |         } else {
6 | |             include_bytes!("../assets/icon.png")
  | |             ^^^^^^^^^^^^^^^^^^^^^^^^^ expected an array with a fixed size of 63249 elements, found one with 471 elements
7 | |         };
  | |_________- `if` and `else` have incompatible types
  |
  = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)

虽然我知道为什么会发生这个错误,但是有没有比下面列出的代码更好的方法来解决这个问题呢?

    let (icon_rgba, icon_width, icon_height) = {
        if cfg!(target_os = "macos") {
            let icon = include_bytes!("../assets/icon-macos.png");
            let image = image::load_from_memory(icon)
                .expect("Failed to open icon path")
                .into_rgba8();
            let (width, height) = image.dimensions();
            let rgba = image.into_raw();
            (rgba, width, height)
        } else {
            let icon = include_bytes!("../assets/icon.png");
            let image = image::load_from_memory(icon)
                .expect("Failed to open icon path")
                .into_rgba8();
            let (width, height) = image.dimensions();
            let rgba = image.into_raw();
            (rgba, width, height)
        };
    };

推荐答案

问题是,编译器推断&[u8; <size_of_the_macos_png>]image的类型,因为当它判断它看到的第二个分支时,第一个分支的include_bytes!()解析为image,但是两个类型都不能被强制到另一个,所以编译器抛出一个错误.

幸运的是,您只需给编译器一个类型提示,而不是使用片,它很乐意强制使用片:

    let (icon_rgba, icon_width, icon_height) = {
        let icon: &[u8] = if cfg!(target_os = "macos") {
            include_bytes!("../assets/icon-macos.png")
        } else {
            include_bytes!("../assets/icon.png")
        };
        let image = image::load_from_memory(icon)
            .expect("Failed to open icon path")
            .into_rgba8();
        let (width, height) = image.dimensions();
        let rgba = image.into_raw();
        (rgba, width, height)
    };

您也可以 Select include_bytes!()个调用中的 as &[u8]个或.as_slice()个(或两者都有),但它更冗长,而且有点不对称(甚至更冗长),所以我更喜欢绑定上的类型提示.

Rust相关问答推荐

如何在 struct 中填充缓冲区并同时显示它?

程序退出后只写入指定管道的数据

当rust中不存在文件或目录时,std::FS::File::Create().unwire()会抛出错误

在Rust中,在实现特征`Display`时,如何获取调用方指定的格式?

如何在 struct 的自定义序列化程序中使用serde序列化_WITH

你是如何在铁 rust 一侧的金牛座获得应用程序版本的?

在IntoIter上调用.by_ref().Take().rev()时会发生什么情况

关于 map 闭合求和的问题

在Rust中声明和定义一个 struct 体有什么区别

循环访问枚举中的不同集合

如何迭代属性以判断相等性?

你能在Rust中弃用一个属性吗?

找不到 .has_func 或 .get_func 的 def

为什么将易错函数的泛型结果作为泛型参数传递 infer ()?不应该是暧昧的吗?

Rust FFI 和 CUDA C 性能差异

在1.5n次比较中找到整数向量中的最大和次大整数

从 Cranelift 发出 ASM

如何为返回正确类型的枚举实现 get 方法?

有没有更好的方法来为拥有 DIsplay 事物集合的 struct 实现 Display?

如何将 while 循环内的用户输入添加到 Rust 中的向量?