首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么临时变量会抑制“类型归属是实验性的”错误?

为什么临时变量会抑制“类型归属是实验性的”错误?
EN

Stack Overflow用户
提问于 2019-11-02 16:46:35
回答 1查看 103关注 0票数 0

我使用Serde机箱将JSON文件反序列化为struct,其中一个属性是可选的。当属性缺少默认值(从命令行)时,它将被替换。这导致我修改我的代码,这会引发以下错误,并且很难找到如何修复它。

我的问题是,除非我将值赋值给一个临时变量,否则我将得到type ascription is experimental error,而且我不明白为什么。我将展示代码并为Config编写结构,因为我认为这部分并不重要。

下面是工作的代码:

代码语言:javascript
复制
    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
        })
    }

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

代码语言:javascript
复制
    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程序员。我只是不明白这个错误,而且我在谷歌上搜索了它,没有做任何明确的解释。从我的角度来看,来自其他语言的我看不出这里有什么不同,也不明白是什么问题是固定的,或者是为什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-02 19:05:18

要将我的注释扩展为一个答案,类型归属是当变量的类型使用冒号显式标注时。这方面的一个例子已经出现在您的代码中:config: Config,这意味着config具有Config类型。大多数情况下,Rust能够根据变量的值推断变量的类型,因此不需要类型归属。事实上,除了一些特殊的实例之外,语言中甚至还不允许进行类型归属(参见本期)。

现在允许类型归属的主要位置是在声明变量时。这是你说类似let x: u32 = 7;let mut s: String = "abc".to_string();之类的话的时候。类似地,在定义结构时,可以使用类型归属来描述其字段:

代码语言:javascript
复制
struct Foo {
    bar: Vec<i32>,
    baz: String,
}

类型归属可以(或必须)使用的另一个主要位置是函数和闭包参数。例如

代码语言:javascript
复制
fn add_one(x: u64) -> u64 {
    x + 1
}

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

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58673177

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档