我试图改变图标(我使用image
crate加载)的应用程序的基础上的设备,应用程序正在编译。不幸的是,当尝试运行代码时:
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)
};
};
2条答案
按热度按时间2exbekwf1#
即使
cfg
在类型检查之前被计算,你的代码也不能编译。这是因为尽管编译器将cfg!(...)
评估为true
或false
,但它不会评估if
块。要让编译器有条件地只发出一个分支,你必须使用
#[cfg(...)]
属性:bf1o4zei2#
问题是编译器将
&[u8; <size_of_the_macos_png>]
推断为image
的类型,因为这是第一个分支的include_bytes!()
解析的类型,当它检查第二个分支时,它看到的是&[u8; <size_of_the_other_png>]
,但两种类型都不能强制转换为另一种类型,因此编译器抛出错误。幸运的是,你可以给予编译器一个类型提示,让它使用切片,它很乐意强制使用切片:
您也可以使用
as &[u8]
或.as_slice()
中的一个(或两个)include_bytes!()
调用,但它更详细,而且有点不对称(甚至更详细),所以我更喜欢绑定上的类型提示。