为什么临时变量会抑制“类型归因于实验”错误?

问题描述 投票:0回答:1

我正在使用Serde JSON板条箱将JSON文件反序列化为结构,并且其中一个属性是可选的。当属性缺少默认值(从命令行)时,它将被替换。这导致我修改代码,从而引发以下错误,并且很难弄清楚如何解决它。

我的问题是,除非将值分配给临时变量,否则我会得到type ascription is experimental error,但我不明白为什么。我将显示代码,并忽略Config的结构,因为我认为这并不重要。

这里是有效的代码:

    pub fn new(file_name: &str, param_urls: &[String]) -> Result<Config, io::Error> {
        let mut config: Config = Config {
            queue: None
        };
        if Path::new(file_name).exists() {
            let json = read_to_string(file_name)?;
            let c: Config = serde_json::from_str(&json)?;
            config = c;
            // ^^^^^^^ must use temporary c variable
        }
        if config.queue.is_none() {
            config.queue = Some(param_urls.to_vec());
        }
        Ok(Config {
            queue: None
        })
    }

上面花了我一段时间才弄清楚,我不明白为什么它可以解决错误,但是这里是引发错误的原始源代码。

    pub fn new(file_name: &str, param_urls: &[String]) -> Result<Config, io::Error> {
        let mut config: Config = Config {
            queue: None
        };
        if Path::new(file_name).exists() {
            let json = read_to_string(file_name)?;
            config: Config = serde_json::from_str(&json)?;
            // ^^^^^^^^^^^ ERROR! type ascription is experimental error
        }
        if config.queue.is_none() {
            config.queue = Some(param_urls.to_vec());
        }
        Ok(Config {
            queue: None
        })
    }

作为来自其他语言的新Rust程序员。我根本不理解此错误,并且在没有任何明确解释的情况下对Google进行了搜索。从我的角度来看,来自其他语言,在这里我看不出有什么区别,也不了解解决了什么问题或原因。

compiler-errors rust
1个回答
3
投票

为了将我的评论扩展为答案,请使用冒号显式表示变量的类型,然后输入类型。在您的代码中已经有一个示例:config: Config,表示config的类型为Config。大多数时候,Rust能够根据变量的值推断出变量的类型,因此不需要类型说明。实际上,除少数特殊情况外,该语言甚至还不允许输入类型说明(请参见this issue)。

现在允许类型归类的主要地方是在声明变量时。这是当您说let x: u32 = 7;let mut s: String = "abc".to_string();之类的内容时。同样,在定义结构时,可以使用类型说明来描述其字段:

struct Foo {
    bar: Vec<i32>,
    baz: String,
}

可以(或必须)使用类型说明的另一个主要地方是在函数和闭包参数中。例如

fn add_one(x: u64) -> u64 {
    x + 1
}

let f = |t: String| t + "123"。使用闭包时,通常可以根据闭包的使用方式来推断变量的类型,但是有时它有助于编译器或读者明确声明参数的类型。

在您的特定情况下,您正在使用类型说明进行重新分配操作,该操作目前不属于允许类型说明的任何类别。 config: Config = serde_json::from_str(&json)?;可以毫无问题地更改为config = serde_json::from_str(&json)?;,因为编译器已经知道config的类型为Config。重新分配很少需要类型归属,因为它不能更改变量的类型。

© www.soinside.com 2019 - 2024. All rights reserved.