如何将 u32 常量转换为 i32 常量而不会在 Rust 中不安全?

问题描述

我试图从现有的 u32 常量定义一个新的 i32 常量,用于匹配表达式,因为 io::Error::raw_os_error() 返回一个 i32,但 winapi 错误常量是 u32。

在下面的代码示例中,现有的 u32 常量将为 ERROR_NO_MORE_FILES

我发现这样做的唯一方法是使用不安全的块。

我是 Rust 的新手,所以有没有办法在不安全的情况下将 u32 转换为 i32 常量?

use std::io::Error;
use std::convert::TryFrom;

const ERROR_NO_MORE_FILES: u32 = 18; // defined in winapi winerror
const ERROR_NO_MORE_FILES_I32: i32 = unsafe { ERROR_NO_MORE_FILES as i32 };
// Attempted to use safe conversion does not compile:
// error[E0015]: calls in constants are limited to constant functions,tuple structs and tuple variants
// const ERROR_NO_MORE_FILES_I32: i32 = i32::try_from(ERROR_NO_MORE_FILES).unwrap();

fn main() -> Result<(),Error> {
    let err = Error::last_os_error();
    match err.raw_os_error() { // an i32
        Some(ERROR_NO_MORE_FILES_I32)  => { println!("No more files..."); },Some(_) => return Err(err),_  => {}
    }
    Ok(())
}


解决方法

正如@loganfsmyth 指出的那样,在这种情况下我不需要 unsafe。我不确定我是如何设法错过警告的(可能应该这么晚才停止编码)...

这编译得很好:

const ERROR_NO_MORE_FILES: u32 = 18; // defined in winapi winerror
const ERROR_NO_MORE_FILES_I32: i32 = ERROR_NO_MORE_FILES as i32;

fn main() {
    println!("{}",ERROR_NO_MORE_FILES_I32);
}