Error handling 为什么你不能使用?(问号)直接在铁锈中收集()吗?

Error handling 为什么你不能使用?(问号)直接在铁锈中收集()吗?,error-handling,rust,iterator,Error Handling,Rust,Iterator,假设我们有一个缓冲读卡器,并希望从中收集行,并使用?传播任何错误: 我的问题是这是需要的方式,以及this::的确切含义和作用 请记住,我刚开始学习Rust。有几个部分结合在一起,这意味着编译器需要一些帮助: collect具有泛型类型 我们可以从中看出,它接受一个名为B的泛型类型,这就是它返回的类型。对于一个函数来说,返回泛型类型有点不寻常。更常见的是,它们接受具有泛型类型的参数,但是返回泛型类型可以产生一些真正有趣、多功能的API,collect肯定是其中之一!有点谈论这个 稍微简化代码,这

假设我们有一个缓冲读卡器,并希望从中收集行,并使用?传播任何错误:

我的问题是这是需要的方式,以及this::的确切含义和作用


请记住,我刚开始学习Rust。

有几个部分结合在一起,这意味着编译器需要一些帮助:

collect具有泛型类型 我们可以从中看出,它接受一个名为B的泛型类型,这就是它返回的类型。对于一个函数来说,返回泛型类型有点不寻常。更常见的是,它们接受具有泛型类型的参数,但是返回泛型类型可以产生一些真正有趣、多功能的API,collect肯定是其中之一!有点谈论这个

稍微简化代码,这意味着编译器不能只查看代码:

让lines=rdr.lines.collect; 并且知道行应该有什么类型。例如,如果您从函数返回行,它可以判断collect的返回类型应该与函数的返回类型完全相同,或者将其用作另一个函数的参数,它可以统一这些类型,但这本身还不够

那么-编译器可以使用什么上下文来计算它应该收集到的类型。。。事实上你有一个?给它一个提示,但是:

? 不仅仅是为了结果 ??可用于实现当前不稳定且可能即将更改特性的任何类型。这意味着编译器不能使用问号来推断您收集到的类型是一个结果-可能您收集到的是一个选项,或者其他实现Try的类型

? 也叫进! 比那更糟?实际上并不仅仅返回结果的错误分支,如果需要,它还会尝试执行转换。例如,如果您有一个函数,该函数的结果是您可以编写ErrString::fromfoo?生锈会把它变成这样:

如果让Errerr=ErrString::fromfoo{ 返回错误; } 因为Into特性是为这些类型实现的,所以字符串可以转换为带有Into的框,所以?操作员可以节省您自己进行转换的时间

然而,这增加了一个完整的间接层次,编译器不能总是做出一些明显的推断,因为错误类型collect returns可能与函数的返回类型不同,但可以转换为它

类型归属 你可以把这些信息放在一个地方,那就是你可以把变量的类型归因于它。因此,您可以编写以下代码:

让行:Result=rdr.lines.collect; 让线=线?; 每一个都是一个地方,在这里,你要求编译器根据它所拥有的信息计算出应该存在的类型。事实上,让lines=rdr.lines.collect;与let行相同:=rdr.lines.collect;-如果编译器能解决,它会,但如果不能,它会给出一个错误,告诉你需要给它更多的信息

在这个代码段中,我们说collect的返回类型需要是一个结果,其中Ok类型是某个编译器的Vec,你计算出来,错误类型是,好吧,编译器,请也计算出来

这为编译器提供了大量信息,在很多情况下这已经足够了,尽管有时我们需要自己填写更多的信息

类型归属需要一个变量-输入turbofish 但是我上面写的代码比您写的代码要详细一点。我们有两个陈述而不是一个,我们有两个变量而不是一个。还有很多的重点是什么?运算符是为了让我们编写简洁的代码

您发现的语法通俗地称为turbofish,因为::看起来有点滑稽,它是一种明确表示collect函数采用的泛型类型的方法:

收款人: 这意味着:调用函数collect,其泛型类型应该是Result。就像我们指定变量的类型一样,这是一种向编译器提供函数的泛型类型信息的方法

因此,把这些放在一起,我们可以写:

让lines=rdr.lines.collect::?;
也就是对编译器说:我希望您调用collect-我希望collect返回的泛型类型是一个Vec的结果,编译器可以计算出剩余的部分,然后它知道您希望收集什么。

有几个部分组合在一起,这意味着编译器需要一些帮助:

collect具有泛型类型 我们可以从中看出,它接受一个名为B的泛型类型,这就是它返回的类型。对于一个函数来说,返回泛型类型有点不寻常。更常见的是,它们接受具有泛型类型的参数,但返回泛型类型可能会导致一些真正的交互 测试、多功能API和收集绝对是其中之一!有点谈论这个

稍微简化代码,这意味着编译器不能只查看代码:

让lines=rdr.lines.collect; 并且知道行应该有什么类型。例如,如果您从函数返回行,它可以判断collect的返回类型应该与函数的返回类型完全相同,或者将其用作另一个函数的参数,它可以统一这些类型,但这本身还不够

那么-编译器可以使用什么上下文来计算它应该收集到的类型。。。事实上你有一个?给它一个提示,但是:

? 不仅仅是为了结果 ??可用于实现当前不稳定且可能即将更改特性的任何类型。这意味着编译器不能使用问号来推断您收集到的类型是一个结果-可能您收集到的是一个选项,或者其他实现Try的类型

? 也叫进! 比那更糟?实际上并不仅仅返回结果的错误分支,如果需要,它还会尝试执行转换。例如,如果您有一个函数,该函数的结果是您可以编写ErrString::fromfoo?生锈会把它变成这样:

如果让Errerr=ErrString::fromfoo{ 返回错误; } 因为Into特性是为这些类型实现的,所以字符串可以转换为带有Into的框,所以?操作员可以节省您自己进行转换的时间

然而,这增加了一个完整的间接层次,编译器不能总是做出一些明显的推断,因为错误类型collect returns可能与函数的返回类型不同,但可以转换为它

类型归属 你可以把这些信息放在一个地方,那就是你可以把变量的类型归因于它。因此,您可以编写以下代码:

让行:Result=rdr.lines.collect; 让线=线?; 每一个都是一个地方,在这里,你要求编译器根据它所拥有的信息计算出应该存在的类型。事实上,让lines=rdr.lines.collect;与let行相同:=rdr.lines.collect;-如果编译器能解决,它会,但如果不能,它会给出一个错误,告诉你需要给它更多的信息

在这个代码段中,我们说collect的返回类型需要是一个结果,其中Ok类型是某个编译器的Vec,你计算出来,错误类型是,好吧,编译器,请也计算出来

这为编译器提供了大量信息,在很多情况下这已经足够了,尽管有时我们需要自己填写更多的信息

类型归属需要一个变量-输入turbofish 但是我上面写的代码比您写的代码要详细一点。我们有两个陈述而不是一个,我们有两个变量而不是一个。还有很多的重点是什么?运算符是为了让我们编写简洁的代码

您发现的语法通俗地称为turbofish,因为::看起来有点滑稽,它是一种明确表示collect函数采用的泛型类型的方法:

收款人: 这意味着:调用函数collect,其泛型类型应该是Result。就像我们指定变量的类型一样,这是一种向编译器提供函数的泛型类型信息的方法

因此,把这些放在一起,我们可以写:

让lines=rdr.lines.collect::?;
也就是对编译器说:我希望你调用collect-我希望collect返回的泛型类型是一个Vec的结果,编译器可以计算出其余的结果,然后它就知道你想收集什么了。

我个人写的let-lines:Vec=rdr.lines.collect::将此报告为一个令人困惑的编译器诊断可能是有意义的。我希望编译器会说一些类似于无法推断collect的返回类型的话,需要类型注释。@user4815162342将此案例添加到链接的Github问题中。谢谢。但是,请注意,问题中涉及的问题是三年前的、封闭的,并且投诉的诊断明显优于您得到的诊断。考虑只报告一个新的问题,以便您的案例可以分开检查。个人来说,我写的是:VEC= RDR.Leal.Copy::把这个报告作为一个混乱的编译器诊断可能是有意义的。我希望编译器会说一些类似于无法推断collect的返回类型的话,需要类型注释。@user4815162342将此案例添加到链接的Github问题中。谢谢。但是,请注意,问题中涉及的问题是三年前的、封闭的,并且投诉的诊断明显优于您得到的诊断。考虑只报告一个新的问题,这样你的案子就可以检查了。 当然。
let lines: Vec<_> = rdr.lines().collect()?;
let lines: Vec<_> = rdr.lines().collect::<Result<Vec<_>,_>>()?;