Types 为什么Rust编译器可以在分离的行上推断类型,但如果合并到一行中就不能?

Types 为什么Rust编译器可以在分离的行上推断类型,但如果合并到一行中就不能?,types,syntax,rust,compiler-construction,type-inference,Types,Syntax,Rust,Compiler Construction,Type Inference,为什么允许这样做: let payload = "key1=value1"; let value: Vec<&str> = payload.split("=").collect(); let value = value[1]; println!("value is {:?}", value); B不可接受: (expression)(suffix) 考虑到表达式“基本上增加了值=值”,这是一种重言式,没有添加任何

为什么允许这样做:

let payload = "key1=value1";
let value: Vec<&str> = payload.split("=").collect();
let value = value[1];
println!("value is {:?}", value);
B不可接受:

(expression)(suffix)
考虑到表达式“基本上增加了值=值”,这是一种重言式,没有添加任何新信息

如果表达式和表达式'具有相同的信息范围,为什么B对编译器无效?如果没有新的信息,为什么不能在B中推断出相同的事情

我质疑的是“无法推断”部分,而不是“应该是XX,因为YY语法/约定”

这仅仅是一个编译器限制或故意错误,以加强易读性,还是从一个案例到另一个案例添加了唯一的信息?逻辑上不同的场景。

您在迭代器上使用的方法需要一个类型来知道它应该收集到什么

此外,提取第一个令牌不需要收集

let value = payload.split("=").nth(1).unwrap(); // you need to better error handling
println!("value is {:?}", value);
如果您想使用第二个示例,可以使用turbofish语法来实现

let value = payload.split("=").collect::<Vec<&str>>()[1];
println!("value is {:?}", value);
第一段,

let value: Vec<&str> = payload.split("=").collect();
let value = value[1];
这是说收集一个迭代器到…某物。。。并将其索引为1,结果类型应为Vec。现在,由于任何数量的类型都可能在索引时生成Vec,它可能是Vec、HashMap,甚至是本项目中定义的某种类型或依赖项,Rust不会在这里尝试猜测。因为它不知道收集到什么类型,所以放弃并返回该错误

要在一行中正确执行此操作,您可能需要使用ol'turbofish语法来指示要收集到的类型

let value = payload.split("=").collect::<Vec<_>>()[1];
注意,Vec元素的类型是已知的,因为它只是迭代器元素的类型。这就是为什么我们可以使用Vec让编译器推断出正确的类型


还有一件事。为了更加习惯,您可以在payload.split=中使用char而不是单个字符串。payload.split'='也可以工作。

在第二个示例中,您的类型注释无效。你想要的是:

let payload = "key1=value1";
let value: &str = payload.split("=").collect::<Vec<&str>>()[1];
println!("value is {:?}", value);
可以简化为:

let payload = "key1=value1";
let value = payload.split("=").collect::<Vec<_>>()[1];
println!("value is {:?}", value);
需要显式的原因是,迭代器可以被收集到十几种不同的集合类型中,而编译器无法猜测您想要哪种类型

let payload = "key1=value1";
let value: &str = payload.split("=").collect::<Vec<&str>>()[1];
println!("value is {:?}", value);
let payload = "key1=value1";
let value = payload.split("=").collect::<Vec<_>>()[1];
println!("value is {:?}", value);