我使用Serde机箱将JSON文件反序列化为struct,其中一个属性是可选的。当属性缺少默认值(从命令行)时,它将被替换。这导致我修改我的代码,这会引发以下错误,并且很难找到如何修复它。
我的问题是,除非我将值赋值给一个临时变量,否则我将得到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程序员。我只是不明白这个错误,而且我在谷歌上搜索了它,没有做任何明确的解释。从我的角度来看,来自其他语言的我看不出这里有什么不同,也不明白是什么问题是固定的,或者是为什么。
发布于 2019-11-02 19:05:18
要将我的注释扩展为一个答案,类型归属是当变量的类型使用冒号显式标注时。这方面的一个例子已经出现在您的代码中:config: Config,这意味着config具有Config类型。大多数情况下,Rust能够根据变量的值推断变量的类型,因此不需要类型归属。事实上,除了一些特殊的实例之外,语言中甚至还不允许进行类型归属(参见本期)。
现在允许类型归属的主要位置是在声明变量时。这是你说类似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类型,所以很可能没有任何问题地将config更改为Config。重新分配很少需要类型归属,因为它不能更改变量的类型。
https://stackoverflow.com/questions/58673177
复制相似问题