<p><spanclass="caption">Listing 9-2: Opening a file</span></p>
<p>如何知道<code>File::open</code>返回一个<code>Result</code>呢?我们可以查看标准库 API 文档,或者可以直接问编译器!如果给<code>f</code>某个我们知道<strong>不是</strong>函数返回值类型的类型注解,接着尝试编译代码,编译器会告诉我们类型不匹配。然后错误信息会告诉我们<code>f</code>的类型<strong>应该</strong>是什么,为此我们将<code>let f</code>语句改为:</p>
<p>在 match guard 中我们想要检查的条件是<code>error.kind()</code>是否是<code>ErrorKind</code>枚举的<code>NotFound</code>成员。如果是,尝试用<code>File::create</code>创建文件。然而<code>File::create</code>也可能会失败,我们还需要增加一个内部<code>match</code>语句。当文件不能被打开,会打印出一个不同的错误信息。外部<code>match</code>的最后一个分支保持不变这样对任何除了文件不存在的错误会使程序 panic。</p>
@ -87,7 +87,7 @@ let home = "127.0.0.1".parse::<IpAddr>().unwrap();
</code></pre>
<p>我们通过解析一个硬编码的字符来创建一个<code>IpAddr</code>实例。可以看出<code>127.0.0.1</code>是一个有效的 IP 地址,所以这里使用<code>unwrap</code>是没有问题的。然而,拥有一个硬编码的有效的字符串也不能改变<code>parse</code>方法的返回值类型:它仍然是一个<code>Result</code>值,而编译器仍然就好像还是有可能出现<code>Err</code>成员那样要求我们处理<code>Result</code>,因为编译器还没有智能到可以识别出这个字符串总是一个有效的 IP 地址。如果 IP 地址字符串来源于用户而不是硬编码进程序中的话,那么就<strong>确实</strong>有失败的可能性,这时就绝对需要我们以一种更健壮的方式处理<code>Result</code>了。</p>
<pre><codeclass="language-rust,ignore">impl Summarizable for NewsArticle {}
</code></pre>
@ -284,8 +268,7 @@ error[E0507]: cannot move out of borrowed content
</code></pre>
<p>错误的核心是<code>cannot move out of type [T], a non-copy array</code>,对于非泛型版本的<code>largest</code>函数,我们只尝试了寻找最大的<code>i32</code>和<code>char</code>。正如第四章讨论过的,像<code>i32</code>和<code>char</code>这样的类型是已知大小的并可以储存在栈上,所以他们实现了<code>Copy</code> trait。当我们将<code>largest</code>函数改成使用泛型后,现在<code>list</code>参数的类型就有可能是没有实现<code>Copy</code> trait 的,这意味着我们可能不能将<code>list[0]</code>的值移动到<code>largest</code>变量中。</p>
<p>让我们如何通过传递拥有不同具体生命周期的引用来观察他们是如何限制<code>longest</code>函数的使用的。列表 10-22 是一个应该在任何编程语言中都很直观的例子:<code>string1</code>直到外部作用域结束都是有效的,<code>string2</code>则在内部作用域中是有效的,而<code>result</code>则引用了一些直到外部作用域结束都是有效的值。借用检查器赞同这些代码;它能够编译和运行,并打印出<code>The longest string is long string is long</code>:</p>
<p><spanclass="caption">Listing 11-4: Test results when one test passes and one
test fails </span></p>
<p><code>test tests::another</code>这一行是<code>FAILED</code>而不是<code>ok</code>了。在单独测试结果和总结之间多了两个新的部分:第一个部分显示了测试失败的详细原因。在这个例子中,<code>another</code>因为<code>panicked at 'Make this test fail'</code>而失败,这位于 <em>src/lib.rs</em> 的第 9 行。下一部分仅仅列出了所有失败的测试,这在很有多测试和很多失败测试的详细输出时很有帮助。可以使用失败测试的名称来只运行这个测试,这样比较方便调试;下一部分会讲到更多运行测试的方法。</p>
<spanclass="caption">Listing 9-2: Opening a file</span>
如何知道`File::open`返回一个`Result`呢?我们可以查看标准库 API 文档,或者可以直接问编译器!如果给`f`某个我们知道**不是**函数返回值类型的类型注解,接着尝试编译代码,编译器会告诉我们类型不匹配。然后错误信息会告诉我们`f`的类型**应该**是什么,为此我们将`let f`语句改为:
在 match guard 中我们想要检查的条件是`error.kind()`是否是`ErrorKind`枚举的`NotFound`成员。如果是,尝试用`File::create`创建文件。然而`File::create`也可能会失败,我们还需要增加一个内部`match`语句。当文件不能被打开,会打印出一个不同的错误信息。外部`match`的最后一个分支保持不变这样对任何除了文件不存在的错误会使程序 panic。
@ -196,8 +181,6 @@ thread 'main' panicked at 'Failed to open hello.txt: Error { repr: Os { code:
Listing 10-21: The `longest` function definition that specifies all the
references in the signature must have the same lifetime, `'a`
</figcaption>
</figure>
<spanclass="caption">Listing 10-21: The `longest` function definition that
specifies all the references in the signature must have the same lifetime,
`'a`</span>
这段代码能够编译并会产生我们想要使用列表 10-19 中的`main`函数得到的结果。
@ -261,7 +225,6 @@ references in the signature must have the same lifetime, `'a`
让我们如何通过传递拥有不同具体生命周期的引用来观察他们是如何限制`longest`函数的使用的。列表 10-22 是一个应该在任何编程语言中都很直观的例子:`string1`直到外部作用域结束都是有效的,`string2`则在内部作用域中是有效的,而`result`则引用了一些直到外部作用域结束都是有效的值。借用检查器赞同这些代码;它能够编译和运行,并打印出`The longest string is long string is long`:
<spanclass="caption">Listing 11-4: Test results when one test passes and one
test fails </span>
`test tests::another`这一行是`FAILED`而不是`ok`了。在单独测试结果和总结之间多了两个新的部分:第一个部分显示了测试失败的详细原因。在这个例子中,`another`因为`panicked at 'Make this test fail'`而失败,这位于 *src/lib.rs* 的第 9 行。下一部分仅仅列出了所有失败的测试,这在很有多测试和很多失败测试的详细输出时很有帮助。可以使用失败测试的名称来只运行这个测试,这样比较方便调试;下一部分会讲到更多运行测试的方法。