<?xml version='1.0' encoding='UTF-8'?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><title>poly000客栈</title><link>/</link><description>poly000 的碎碎念</description><docs>http://www.rssboard.org/rss-specification</docs><generator>python-feedgen</generator><image><url>/android-chrome-512x512.png</url><title>poly000客栈</title><link>/</link></image><language>chinese</language><lastBuildDate>Wed, 03 Jun 2026 20:29:11 +0806</lastBuildDate><pubDate>Wed, 03 Jun 2026 20:29:11 +0806</pubDate><item><title>一些不错的Rust Unstable特性</title><link>/archives/awesome-unstable-rust-features/</link><description>&lt;h2&gt;注意&lt;/h2&gt;
&lt;p&gt;本文原文发布于2021-07-26，其中部分内容可能已经过时。请以 Rust RFC 为准。
已经稳定的特性见 &lt;a href="https://github.com/rust-lang/rust/blob/master/compiler/rustc_feature/src/accepted.rs"&gt;accepted.rs&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;最后一次更新：2024-02-08&lt;/p&gt;&lt;h2&gt;关于翻译&lt;/h2&gt;
&lt;p&gt;主要译者：&lt;a href="https://github.com/poly000"&gt;poly000&lt;/a&gt;，&lt;a href="https://t.me/Hinanawi_Tenshi_M"&gt;比那名居&lt;/a&gt;&lt;/p&gt;&lt;p&gt;术语翻译部分参考了 &lt;a href="https://rustwiki.org/wiki/translate/english-chinese-glossary-of-rust/"&gt;Rust 语言术语中英文对照表&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;如果有原文错误，请联系 &lt;a href="https://twitter.com/efun_b"&gt;Ethan Brierley&lt;/a&gt; 且联系我更新翻译。&lt;/p&gt;&lt;p&gt;参与：&lt;a href="https://github.com/poly000/Maverick/"&gt;Maverick/demo_src&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Credits&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://lazy.codes/posts/awesome-unstable-rust-features/"&gt;原文&lt;/a&gt; by &lt;a href="https://twitter.com/efun_b"&gt;Ethan Brierley&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;简介&lt;/h2&gt;
&lt;p&gt;这篇文章介绍了一些尚不稳定的 Rust 编译器特性。我将会简单叙述这些特性，并不会深入太多细节。&lt;/p&gt;&lt;h2&gt;什么是Unstable Rust？&lt;/h2&gt;
&lt;p&gt;Rust 有三个发布版本： stable，beta，nightly。&lt;/p&gt;&lt;p&gt;Nightly 编译器每天都会发布，而且只有它允许你启用 Unstable Rust 特性。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;这篇文章只讨论 Unstable 编译器特性，不讨论此版本的标准库特性。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2&gt;为什么要用 Unstable 特性？&lt;/h2&gt;
&lt;p&gt;Unstable Rust 可以让你使用在Stable Rust 中不允许使用的API。为此，编译器与标准库都使用了 Unstable 特性。&lt;/p&gt;&lt;p&gt;使用 Unstable 特性总是伴随着一些风险。它们经常会有一些不期望行为，有时甚至会破坏 Rust 的内存安全保证，导致未定义行为。这些特性可能开发的很好，但也能未开发完善。&lt;/p&gt;&lt;p&gt;使用Unstable特性的 Nightly 编译器，遇到“内部编译器错误”并不少见，这种情况通常称为&lt;a href="https://github.com/rust-lang/rust/labels/I-ICE"&gt;ICE&lt;/a&gt;。它发生于编译过程中，编译器将会panic。这可能是由于数据与查询操作因未完成的特性而被破坏，甚至可能只是因为没做完的特性中打了个 &lt;code&gt;todo!()&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;如果你遇到了ICE，检查一下是否已经被反馈，没有的话就把它报告给&lt;a href="https://github.com/rust-lang/rust/issues"&gt;bug tracker&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;Rust 不保证在未来继续支持它的 Unstable 特性。
作为 Rust 开发者，我们享受着优秀的向下兼容性与稳定性，
而启用 Unstable 特性时，Rust不再提供这些保证。
今天工作的程序可能明天就寄了！&lt;/p&gt;&lt;p&gt;我决定学习 Unstable 特性，不是因为我需要用它们去解决实际问题，而是觉得他们很有意思。
对我来说，使用 Unstable 特性，可以让我有趣地，更多的参与语言本身的开发过程。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Unstable 特性的完整列表见&lt;a href="https://github.com/rust-lang/rust/blob/135ccbaca86ed4b9c0efaf0cd31442eae57ffad7/src/librustc_feature/active.rs#L83-L530"&gt;Unstable 特性列表&lt;/a&gt;。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2&gt;启用 Unstable 特性&lt;/h2&gt;
&lt;p&gt;若要使用 Unstable 特性，首先你需要安装 Nightly 工具链：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;rustup&lt;span class="w"&gt; &lt;/span&gt;toolchain&lt;span class="w"&gt; &lt;/span&gt;install&lt;span class="w"&gt; &lt;/span&gt;nightly
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;临时使用 Nightly 工具链，你可以在运行cargo时加上 &lt;code&gt;+nightly&lt;/code&gt;。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&amp;lt;rust-command&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;+nightly&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;args&amp;gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;例如：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;cargo&lt;span class="w"&gt; &lt;/span&gt;+nightly&lt;span class="w"&gt; &lt;/span&gt;run
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;另外，你可以将你的默认编译器改为 Nightly ，这样你就不再需要加上 `+nightly。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;rustup&lt;span class="w"&gt; &lt;/span&gt;default&lt;span class="w"&gt; &lt;/span&gt;nightly
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;切换到 nightly 编译器后，你就可以使用 Unstable 特性。让我们试一试吧！&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;my_box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;你会得到如下编译错误：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;E0658&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;syntax&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;experimental&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;you&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;can&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;instead&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;my_box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt;                  &lt;/span&gt;&lt;span class="o"&gt;^^^^^&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;see&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;issue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;49733&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//github.com/rust-lang/rust/issues/49733&amp;gt; for more information&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;help&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="cp"&gt;#![feature(box_syntax)]&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;enable&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Rust 在 &lt;code&gt;help&lt;/code&gt; 消息中准确地告诉了我们应该做什么——
我们需要用 &lt;code&gt;#![feature(box_syntax)]&lt;/code&gt; 启用这个特性。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#![feature(box_syntax)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;my_box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;所有 Unstable 特性都需要用 &lt;code&gt;#![feature(..)]&lt;/code&gt; 启用。
即使你忘记了，编译器通常也会指出要如何做，虽然不总会是。&lt;/p&gt;&lt;p&gt;现在，我们看看这些特性。
我把需要启用的特性名称放在每个特性的标题中的 &lt;code&gt;代码块&lt;/code&gt; 中，在代码片段中省略，以保持简洁。&lt;/p&gt;&lt;h2&gt;控制流、模式和块&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;destructuring_assignment&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;于 Rust 1.59 稳定。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;在Rust中，我们经常在绑定到定义时解构某个类型。
我们一般会使用&lt;code&gt;let&lt;/code&gt;绑定：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// 创建两个变量, 一个是 x, 一个是 y &lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;目前这种写法只得在实例化新的定义时使用。
&lt;code&gt;destructuring_assignment&lt;/code&gt; 将它拓展到赋值。&lt;/p&gt;&lt;p&gt;换句话说，我们可以不使用 &lt;code&gt;let&lt;/code&gt; 完成解构。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;从任意块提前返回，&lt;code&gt;label_break_value&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;于 Rust 1.65 稳定。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Rust 有一个不那么广为人知的特性，&lt;a href="https://doc.rust-lang.org/edition-guide/rust-2018/control-flow/loops-can-break-with-a-value.html"&gt;&lt;code&gt;loop&lt;/code&gt;可以带值退出&lt;/a&gt;。
就像 Rust 中许多其它的结构，在 Rust 中 &lt;code&gt;loop&lt;/code&gt; 并不仅仅是语句, 而是&lt;a href="https://doc.rust-lang.org/reference/statements-and-expressions.html"&gt;表达式&lt;/a&gt;。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// 保持请求用户输入一个数字，直到他们给出一个有效的数字。&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;u8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="fm"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Invaid number, Please input a valid number&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;label_break_value&lt;/code&gt; 把这拓展到任何被标记的块，而不仅仅是 &lt;code&gt;loop&lt;/code&gt;。
它的行为，就像是一种提前的 &lt;code&gt;return&lt;/code&gt; ，不过适用于任何代码块，而不只是函数体。&lt;/p&gt;&lt;p&gt;标记代码块的语法，和生命周期很相似。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="c1"&gt;// 这个代码块现在被标记为 &amp;quot;block&amp;quot; 。&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;现在也可以用同样的方式&lt;a href="https://doc.rust-lang.org/rust-by-example/flow_control/loop/nested.html"&gt;标记&lt;code&gt;loop&lt;/code&gt;&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;我们可以把标签放在 &lt;code&gt;break&lt;/code&gt; 后面，从那个代码块提前返回。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;block&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;&amp;#39;block&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 从代码块提前返回&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;这个特性&lt;a href="http://david.tribble.com/text/goto.html"&gt;不等价于goto&lt;/a&gt;。
它没有 goto 那样的破坏性影响，他只是往后继续执行，从一个代码块中退出。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;使用 &lt;code&gt;try_blocks&lt;/code&gt; 内联 &lt;code&gt;?&lt;/code&gt; 操作符的功能&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/the-question-mark-operator-for-easier-error-handling.html"&gt;版本引导&lt;/a&gt;用这个例子解释问号运算符的工作方式：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;read_username_from_file&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;username.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;使用 &lt;code&gt;?&lt;/code&gt; 操作符简化，可以得到等效的代码：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;read_username_from_file&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;username.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;?&lt;/code&gt; 可以在函数中提前返回 &lt;code&gt;Err&lt;/code&gt;。
&lt;code&gt;try_blocks&lt;/code&gt; 提供了适用于任意代码块的相同功能。
使用 &lt;code&gt;try_blocks&lt;/code&gt; ，我们可以内联 &lt;code&gt;read_usernames_from_file&lt;/code&gt; 函数。&lt;/p&gt;&lt;p&gt;&lt;code&gt;try_blocks&lt;/code&gt; 和 &lt;code&gt;?&lt;/code&gt; 的关系就像是 &lt;code&gt;label_break_value&lt;/code&gt; 和 &lt;code&gt;return&lt;/code&gt; 的关系。
&lt;code&gt;try_blocks&lt;/code&gt; 的RFC提到了 &lt;code&gt;label_break_value&lt;/code&gt; ，作为 &lt;code&gt;try_blocks&lt;/code&gt; 一种可能的解糖。&lt;/p&gt;&lt;p&gt;接下来重写我们的 &lt;code&gt;read_username_from_file&lt;/code&gt; ，
我们得到了一个简单的 &lt;code&gt;let&lt;/code&gt; 绑定和 &lt;code&gt;try&lt;/code&gt; 代码块。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;read_username_from_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;username.txt&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;我喜欢这个特性。特别是对于较小的表达式，如果不提取成函数，可读性会更好。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;inline_const&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;目前，指定某个值编译时计算需要定义一个常量。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PI_APPROX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;f64&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;22.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PI_APPROX&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;有了 &lt;code&gt;inline_const&lt;/code&gt; 我们可以用匿名表达式完成同样的事。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;22.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;7.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在这个简单的例子中， 因为编译器优化 &lt;a href="https://blog.rust-lang.org/inside-rust/2019/12/02/const-prop-on-by-default.html"&gt;constant propagation&lt;/a&gt;，&lt;code&gt;const&lt;/code&gt; 块是不必要的。
但是对于更复杂的常量，用块来表示，可能会更好。&lt;/p&gt;&lt;p&gt;这个特性也允许在const块中使用模式匹配。
如 &lt;code&gt;match x { 1 + 3 =&amp;gt; {} }&lt;/code&gt; 会导致语法错误，而 &lt;code&gt;match x { const { 1 + 3 } =&amp;gt; {} }&lt;/code&gt; 不会。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;if_let_guard&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;拓展 &lt;code&gt;match&lt;/code&gt; 中的 &lt;a href="https://doc.rust-lang.org/beta/rust-by-example/flow_control/match/guard.html"&gt;&lt;code&gt;if&lt;/code&gt; 守卫&lt;/a&gt; ，使其允许使用 &lt;code&gt;if let&lt;/code&gt;。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;let_chains&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;于 Rust 1.64 稳定。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;目前，&lt;code&gt;if let&lt;/code&gt; 和 &lt;code&gt;while let&lt;/code&gt; 表达式不能以 &lt;code&gt;||&lt;/code&gt; 或 &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; 连接，
这个特性添加了支持。&lt;/p&gt;&lt;h2&gt;Traits&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;associated_type_bounds&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是一个 stable Rust 函数：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fizzbuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;FizzBuzz&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Fizz&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Buzz&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;有了 &lt;code&gt;associated_type_bounds&lt;/code&gt; 特性，对于这种情况，我们可以使用一个匿名类型：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fizzbuzz&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Display&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;看看这个冗长重复的函数签名：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;flatten_twice&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Flatten&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Flatten&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Iterator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;IntoIterator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;IntoIterator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;IntoIterator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;有了这个特性，我们就可以简单地写成：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;flatten_twice&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Flatten&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Flatten&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;IntoIterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;IntoIterator&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;flatten&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这种写法容易理解许多。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;default_type_parameter_fallback&lt;/code&gt;, &lt;code&gt;associated_type_defaults&lt;/code&gt;以及&lt;code&gt;const_generics_defaults&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;const_generics_defaults&lt;/code&gt; 于 Rust 1.59 稳定。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;这些特性允许你为 &lt;a href="https://github.com/rust-lang/rfcs/blob/master/text/0213-defaulted-type-params.md"&gt;泛型类型&lt;/a&gt;, &lt;a href="https://github.com/rust-lang/rfcs/blob/master/text/2532-associated-type-defaults.md"&gt;关联类型&lt;/a&gt; 以及 &lt;a href="#const-%E6%B3%9B%E5%9E%8B"&gt;const 变量&lt;/a&gt; 在更多地方指定默认值。&lt;/p&gt;&lt;p&gt;它们允许你作为开发者创建更好的 API 。
如果一个crate的用户对细节不感兴趣，而它有默认值，则可以忽略细节。
这也让拓展 API 变得容易，无需做出破坏性更新。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;negative_impls&lt;/code&gt; 和 &lt;code&gt;auto_traits&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这些特性都被标准库使用。&lt;a href="https://doc.rust-lang.org/std/marker/trait.Send.html"&gt;&lt;code&gt;Send&lt;/code&gt;&lt;/a&gt; 和 &lt;a href="https://doc.rust-lang.org/std/marker/trait.Sync.html"&gt;&lt;code&gt;Sync&lt;/code&gt;&lt;/a&gt; 都是自动 trait。&lt;/p&gt;&lt;p&gt;&lt;code&gt;Send&lt;/code&gt; trait &lt;a href="https://doc.rust-lang.org/src/core/marker.rs.html#38-40"&gt;定义于标准库&lt;/a&gt;：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;unsafe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;trait&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Send&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// 空的&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;注意&lt;code&gt;auto&lt;/code&gt;关键字，它让编译器为任意结构体/枚举体/联合体自动实现 &lt;code&gt;Send&lt;/code&gt; trait，（前提是构成这个类型的类型都实现了&lt;code&gt;Send&lt;/code&gt;）&lt;/p&gt;&lt;p&gt;如果每个类型都能简单地实现自动trait ，它们也不会那么有用。
这正是引入 &lt;code&gt;negative_impls&lt;/code&gt; 的原因。&lt;/p&gt;&lt;p&gt;&lt;code&gt;negative_impls&lt;/code&gt; 允许一个类型不实现某个auto trait。
举个例子，&lt;code&gt;UnsafeCell&lt;/code&gt;。不受限制的 &lt;code&gt;UnsafeCell&lt;/code&gt; 在线程间共享非常不安全，因此它被标记为 &lt;code&gt;Sync&lt;/code&gt; 也不安全。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="nb"&gt;Sized&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;Sync&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UnsafeCell&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;注意 &lt;code&gt;!&lt;/code&gt; ，表示 “不&lt;code&gt;Sync&lt;/code&gt;”。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;marker_trait_attr&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这个特性为 trait 添加了&lt;code&gt;#[marker]&lt;/code&gt; 属性。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;详见 &lt;a href="https://doc.rust-lang.org/beta/unstable-book/language-features/marker-trait-attr.html"&gt;Unstable Book&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Rust 不允许定义trait的实现时覆盖此前的实现。
这样编译器就能确定要使用哪个实现——只有一个。&lt;/p&gt;&lt;p&gt;标志为 &lt;code&gt;#[marker]&lt;/code&gt; 的 trait 不能在实现中覆盖任何东西。
这样它们就能允许重叠的实现，因为所有的实现都是一样的。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;type_alias_impl_trait&lt;/code&gt;, &lt;code&gt;impl_trait_in_bindings&lt;/code&gt; and &lt;code&gt;trait_alias&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;impl Trait&lt;/code&gt; 让编译器推导具体类型，把它换成实现了&lt;code&gt;Trait&lt;/code&gt;的类型。
目前，&lt;code&gt;impl Trait&lt;/code&gt;只能在函数参数或返回类型中使用，无法应用于变量绑定。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;注：impl_trait_in_binding 临时被移除(2022-07-26)，可能是因为它导致了&lt;a href="https://github.com/rust-lang/rust/issues/83021"&gt;破坏性更新&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;需要注意的是，使用 &lt;code&gt;type_alias_impl_trait&lt;/code&gt; 时，类型必须是固定的。编译器会推断且应用单一具体的类型。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#![feature(type_alias_impl_trait)]&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;AsRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;pre&gt;&lt;code&gt;error[E0308]: mismatched types
 --&amp;gt; src/main.rs:9:9
  |
3 | type Foo = impl AsRef&amp;lt;str&amp;gt;;
  |            --------------- the expected opaque type
...
9 |     foo(&amp;quot;&amp;quot;);
  |     --- ^^ expected opaque type, found `&amp;amp;str`
  |     |
  |     arguments to this function are incorrect
  |
  = note: expected opaque type `Foo`
               found reference `&amp;amp;'static str`
note: function defined here
 --&amp;gt; src/main.rs:5:4
  |
5 | fn foo(_: Foo) {}
  |    ^^^ ------
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;&lt;code&gt;fn_traits&lt;/code&gt; and &lt;code&gt;unboxed_closures&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;Fn&lt;/code&gt;，&lt;code&gt;FnMut&lt;/code&gt;和&lt;code&gt;FnOnce&lt;/code&gt;被认为是&lt;code&gt;fn&lt;/code&gt;的trait。
它们会被任何函数或者你创建的闭包自动实现，它们允许你给它们传参。&lt;/p&gt;&lt;p&gt;目前它们只能被自动实现。
&lt;code&gt;fn_trait&lt;/code&gt; 则允许为任意类型提供自定义实现。
这就像是操作符重载，但要自定义的是&lt;code&gt;()&lt;/code&gt;调用。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#![feature(unboxed_closures)]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 实现带有`extern &amp;quot;rust-call&amp;quot;`的函数&lt;/span&gt;
&lt;span class="cp"&gt;#![feature(fn_traits)]&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Multiply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cp"&gt;#[allow(non_upper_case_globals)]&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Multiply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Multiply&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;FnOnce&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Multiply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;rust-call&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;call_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;FnOnce&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Multiply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;rust-call&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;call_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;FnOnce&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="kt"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Multiply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;rust-call&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;call_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="kt"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mf"&gt;0.&lt;/span&gt;&lt;span class="n"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="fm"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="fm"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="fm"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hello &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hello hello hello &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这可被用于实现有点 hacky 的&lt;a href="https://en.wikipedia.org/wiki/Function_overloading"&gt;函数重载&lt;/a&gt;和&lt;a href="https://en.wikipedia.org/wiki/Variadic_function"&gt;不定参函数&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;语法糖&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;box_patterns&lt;/code&gt; and &lt;code&gt;box_syntax&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这两个特性让&lt;code&gt;Box&lt;/code&gt;的构造和析构变得更容易。
box关键字将取代&lt;code&gt;Box::new(...)&lt;/code&gt;，并且允许在模式匹配中解引用&lt;code&gt;Box&lt;/code&gt;。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;TrashStack&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TrashStack&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TrashStack&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Self&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="bp"&gt;Self&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;peek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TrashStack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TrashStack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nb"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;正如原文作者所说，rust（包括内部实现）正在减少box syntax的使用。&lt;/p&gt;&lt;p&gt;所以这个章节咕了（理直气壮）&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This makes things a little more ergonomic but I don't think there is much chance that this feature will ever be stabilised.
It seems to have existed forever with no plan for stabilisation but instead a little discussion about removing the feature.
&lt;code&gt;box_synatx&lt;/code&gt; is used heavily in the compiler's source and a little in the standard library.&lt;/p&gt;&lt;p&gt;It is interesting to note that &lt;code&gt;box&lt;/code&gt; does not desugar to &lt;code&gt;Box::new&lt;/code&gt; but &lt;code&gt;Box::new&lt;/code&gt; is implemented in the standard library with &lt;code&gt;box&lt;/code&gt;.&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Box&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Self&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;box&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;&lt;code&gt;async_closure&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;目前在闭包中使用异步代码你需要加async块。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Hi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;async_closure&lt;/code&gt; 允许你将闭包本身标记为异步的，像异步函数那样写&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Hi&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;&lt;code&gt;in_band_lifetimes&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;于 &lt;a href="https://github.com/rust-lang/rust/pull/93845"&gt;Rust #93845&lt;/a&gt; 移除；&lt;/p&gt;&lt;p&gt;原始 RFC 中，不单独标注的提案被 Rust 拒绝。&lt;/p&gt;&lt;p&gt;详见 &lt;a href="https://github.com/rust-lang/rust/issues/44524#issuecomment-988260463"&gt;Rust #44524&lt;/a&gt; 。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;使用生命周期标记时，必须事先定义：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;使用 &lt;code&gt;in_band_lifetimes&lt;/code&gt; ，生命周期可以不先显式定义。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;Params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这是&lt;a href="https://github.com/rust-lang/rfcs/pull/2115#issuecomment-323221054"&gt;生命周期&lt;/a&gt;在rust &lt;code&gt;1.0.0&lt;/code&gt;前的写法。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;format_args_capture&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;于 Rust 1.58 稳定。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;This allows for named arguments to be placed inside of strings inside any macro that depends on &lt;code&gt;std::format_args!&lt;/code&gt;.
That includes &lt;code&gt;print!&lt;/code&gt;, &lt;code&gt;format!&lt;/code&gt;, &lt;code&gt;write!&lt;/code&gt; and many more.&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Ferris&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="fm"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;你好{name}，你{age}岁了。&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;&lt;code&gt;crate_visibility_modifier&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;已于 &lt;a href="https://github.com/rust-lang/rust/pull/97254"&gt;Rust #97254&lt;/a&gt; 移除。&lt;/p&gt;&lt;p&gt;理由：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;会产生歧义 &lt;sup class="footnote-ref" id="fnref-1"&gt;&lt;a href="#fn-1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;这个特性允许你写 &lt;code&gt;crate struct Foo&lt;/code&gt; 而不是 &lt;code&gt;pub(crate) struct Foo&lt;/code&gt; ，语义不变。&lt;/p&gt;&lt;h2&gt;Types&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;type_ascription&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;已于 &lt;a href="https://github.com/rust-lang/rust/issues/101728"&gt;Rust #101728&lt;/a&gt; 移除&lt;/p&gt;&lt;p&gt;理由：语法不Rust&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;用&lt;code&gt;Iterator&lt;/code&gt;的&lt;code&gt;collect&lt;/code&gt;方法举个例子：
collect将迭代器转换到集合&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="fm"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{:?}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这个不能编译，因为rust无法推导出&lt;code&gt;word&lt;/code&gt;的类型。
可以把第一行换成：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;有了&lt;code&gt;type_ascription&lt;/code&gt;就不需要再加上let绑定，我们可以直接：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="fm"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;{:?}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;: Type&lt;/code&gt; 语法可以用在任何一处，提醒编译器“我在这里想要得到这个类型”&lt;/p&gt;&lt;h3&gt;&lt;code&gt;never_type&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;你可以定义没有变体的枚举体，
这种枚举体也存在于标准库中。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;enum&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Infallible&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;你可以在泛型或函数签名中使用该类型，但它不可能被构造。&lt;/p&gt;&lt;p&gt;元类型 &lt;code&gt;()&lt;/code&gt; 等价于只有一个变体的枚举。
&lt;code&gt;never_type&lt;/code&gt; 引入了一种新的类型，&lt;code&gt;!&lt;/code&gt;等价于没有变体的 &lt;code&gt;Infallible&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;Because &lt;code&gt;!&lt;/code&gt; can never be constructed it can be given special powers.
We don't have to handle the case of &lt;code&gt;!&lt;/code&gt; because we have proven it will never exist.&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;loop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="fm"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Hello, world!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Loops without a &lt;code&gt;break&lt;/code&gt; &amp;quot;return &lt;code&gt;!&lt;/code&gt;&amp;quot; because they don't ever return.&lt;/p&gt;&lt;p&gt;&lt;code&gt;!&lt;/code&gt; can be very useful for expressing impossible outcomes in the type system.
Take for example the &lt;code&gt;FromStr&lt;/code&gt; implementation on this &lt;code&gt;UserName&lt;/code&gt; type.
This implementation is infallible because its implementation can never fail.
This allows us to set the &lt;code&gt;Err&lt;/code&gt; variant to type &lt;code&gt;!&lt;/code&gt;.&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;UserName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FromStr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kp"&gt;&amp;amp;&lt;/span&gt;&lt;span class="kt"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="bp"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Err&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_owned&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It is then possible to use an empty &lt;code&gt;match&lt;/code&gt; on the &lt;code&gt;Err&lt;/code&gt; variant because &lt;code&gt;!&lt;/code&gt; has no variants.&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserName&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ethan&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;&lt;code&gt;exhaustive_patterns&lt;/code&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;译注：原作者的解释和 RFC，Issue 都对不上。&lt;/p&gt;&lt;p&gt;原Issue目标为，不可达的分支可以省略&lt;/p&gt;&lt;p&gt;如析构一个 &lt;code&gt;Result&amp;lt;T, !&amp;gt;&lt;/code&gt; ，&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;safe_unwrap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;With the feature &lt;code&gt;exhaustive_patterns&lt;/code&gt; the type system becomes smart enough for us to eliminate the &lt;code&gt;Err&lt;/code&gt; branch altogether.&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserName&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ethan&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can combine this with destructuring to remove the &lt;code&gt;match&lt;/code&gt; leaving a beautiful line of code.&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;UserName&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;from_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;ethan&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;attribute&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;这个小节由 &lt;a href="https://t.me/Hinanawi_Tenshi_M"&gt;@Hinanawi_Tenshi_M&lt;/a&gt; 提供翻译，有改动&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;&lt;code&gt;optimize_attribute&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;你可以用 &lt;code&gt;Cargo.toml&lt;/code&gt; 的 &lt;a href="https://doc.rust-lang.org/book/ch14-01-release-profiles.html"&gt;&lt;code&gt;opt-level&lt;/code&gt;&lt;/a&gt; 选项指定你想要怎么优化你的二进制文件。&lt;/p&gt;&lt;p&gt;&lt;code&gt;opt-level&lt;/code&gt; 指定的是整个 crate 的优化方式，如果你想要分别控制每一个项目的优化方式，你可以使用 &lt;code&gt;optimize_attribute&lt;/code&gt; 选项。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#[optimize(speed)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;fast_but_large&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cp"&gt;#[optimize(size)]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;slow_but_small&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这对微调应用程序非常有用。在这些应用程序中，大小和性能的权衡特别重要。例如使用 &lt;a href="https://webassembly.org/"&gt;web assembly&lt;/a&gt; 时。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;stmt_expr_attributes&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这个特性让你可以在几乎任何地方标记属性，而不仅仅是顶层项目。例如，你可以在一个闭包上放一个&lt;a href="#%60optimize_attribute%60"&gt;optimize attribute&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;&lt;code&gt;cfg_version&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;该特性允许根据编译器版本进行条件编译。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#[cfg(version(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1.42&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;))]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 1.42 以上&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cp"&gt;#[cfg(not(version(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;1.42&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;)))]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// 1.41 以下&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这使得你的 crate 能够使用最新的编译器功能，同时仍然保持对旧编译器的后备支持。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;no_core&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;不依赖 &lt;code&gt;::std&lt;/code&gt; 的 &lt;code&gt;#![no_std]&lt;/code&gt; 选项已经存在很久了，&lt;/p&gt;&lt;p&gt;&lt;code&gt;#![no_core]&lt;/code&gt; 则对应着不依赖 &lt;code&gt;::core&lt;/code&gt; 。&lt;/p&gt;&lt;p&gt;这对于不在完整环境中运行的应用非常重要，如嵌入式系统。
嵌入式系统通常没有操作系统，甚至没有动态内存，所以 &lt;code&gt;std&lt;/code&gt; 中的许多功能都无法使用。&lt;/p&gt;&lt;p&gt;你现在可以通过 &lt;code&gt;#![no_core]&lt;/code&gt; 表明不使用 libcore。&lt;/p&gt;&lt;p&gt;这样不会留下任何东西——你甚至不能使用libc。&lt;/p&gt;&lt;h2&gt;其它&lt;/h2&gt;
&lt;h3&gt;Const 泛型&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这个小节由 &lt;a href="https://t.me/Hinanawi_Tenshi_M"&gt;@Hinanawi_Tenshi_M&lt;/a&gt; 提供翻译，有改动。&lt;/p&gt;&lt;p&gt;已经在 Stable Rust 部分实现。 &lt;sup class="footnote-ref" id="fnref-2"&gt;&lt;a href="#fn-2"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;在都柏林 Rust 集会中，关于 &lt;code&gt;const_generics&lt;/code&gt; ，我做过一场&lt;a href="https://lazy.codes/posts/intro-to-const-generics/"&gt;演讲&lt;/a&gt;。
与其重复那些内容，我更推荐大家去&lt;a href="https://lazy.codes/posts/intro-to-const-generics/"&gt;看这个演讲&lt;/a&gt;。&lt;/p&gt;&lt;h3&gt;Macros 2.0&lt;/h3&gt;
&lt;p&gt;Rust的声明式宏非常强大。然而， &lt;code&gt;macro_rules!&lt;/code&gt; 的一些规则，让我很困惑。&lt;/p&gt;&lt;p&gt;&lt;code&gt;macro_rules!&lt;/code&gt; 是一个简单的token转换过程，或者说，&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;它接受一个token列表，输出新的token列表&lt;/li&gt;
&lt;li&gt;可见性原则会遵从宏的调用处的规则。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;——因为代码只是被简单地粘贴回原处。&lt;/p&gt;&lt;p&gt;&lt;a href="https://veykril.github.io/tlborm/decl-macros/macros2.html"&gt;Macros 2.0&lt;/a&gt; 介绍了&lt;code&gt;macro_rules!&lt;/code&gt;的一种替代。&lt;/p&gt;&lt;p&gt;编写 Macros 2.0 只需使用关键字 &lt;code&gt;macro&lt;/code&gt;&lt;/p&gt;&lt;p&gt;它引入了一种新的格式，Hygiene 。Hygiene 允许宏应用它们定义处的可见性规则，而不是调用处。&lt;/p&gt;&lt;h3&gt;&lt;code&gt;generators&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;生成器（协程）提供了一种特殊的函数，可以在执行过程中暂停，“yield” 中间值给调用者。&lt;/p&gt;&lt;p&gt;生成器允许你使用&lt;code&gt;yield&lt;/code&gt;关键字返回多个值，每次暂停该函数并返回给调用者。&lt;/p&gt;&lt;p&gt;生成器中也可以&lt;code&gt;return&lt;/code&gt;单个值，不可再恢复。&lt;/p&gt;&lt;p&gt;大约三年前，我尝试编写算法，沿对角线遍历一个无穷的矩阵。我发现用Rust的迭代器编写它非常困难，最终放弃了。&lt;/p&gt;&lt;p&gt;这是我的实现，使用了Rust的生成器（协程）和一些我们刚刚讨论过的特性。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#![feature(&lt;/span&gt;
&lt;span class="cp"&gt;    try_blocks,&lt;/span&gt;
&lt;span class="cp"&gt;    generators,&lt;/span&gt;
&lt;span class="cp"&gt;    generator_trait,&lt;/span&gt;
&lt;span class="cp"&gt;    associated_type_bounds,&lt;/span&gt;
&lt;span class="cp"&gt;    type_ascription&lt;/span&gt;
&lt;span class="cp"&gt;)]&lt;/span&gt;

&lt;span class="k"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;ops&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Generator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GeneratorState&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;pin&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="sd"&gt;/// Input&lt;/span&gt;
&lt;span class="sd"&gt;/// [[1, 2, 3]&lt;/span&gt;
&lt;span class="sd"&gt;/// ,[4, 5, 6]&lt;/span&gt;
&lt;span class="sd"&gt;/// ,[7, 8, 9]]&lt;/span&gt;
&lt;span class="sd"&gt;/// Output&lt;/span&gt;
&lt;span class="sd"&gt;/// [1, 2, 4, 3, 5, 7]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;diagonalize&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;impl&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Generator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Yield&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;||&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;                        &lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="kr"&gt;yield&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}):&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;cycle&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;diagonals&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;diagonalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GeneratorState&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Yielded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Pin&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;diagonals&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;resume&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="fm"&gt;dbg!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;It is understandable if you found the above snippet hard to interpret.
It makes use of a number of features that you may have just been introduced to.&lt;/p&gt;&lt;p&gt;There is a compelling argument against adding too many new features as they can greatly increase the learning curve.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;生成器让一些没有这个特性会难以编写甚至无法编写的实现变为可能。&lt;/p&gt;&lt;p&gt;生成器在标准库中是为了实现 async/await 添加的。
具体的语义在稳定化前很可能被修改，但它很有趣。&lt;/p&gt;&lt;h3&gt;总结&lt;/h3&gt;
&lt;p&gt;我很抱歉，没有介绍其他三个不错的unstable特性：&lt;a href="https://github.com/rust-lang/rfcs/blob/master/text/1598-generic_associated_types.md"&gt;GAT&lt;/a&gt;, &lt;a href="https://rust-lang.github.io/rfcs/2873-inline-asm.html"&gt;内联汇编&lt;/a&gt;和&lt;a href="https://rust-lang.github.io/rfcs/1210-impl-specialization.html"&gt;特化&lt;/a&gt;。
我只是感觉，在这篇文章中，我做不到客观的评价它们，不过将来我可能会尝试。&lt;/p&gt;&lt;p&gt;如果你想了解更多unstable特性，我推荐你看&lt;a href="https://doc.rust-lang.org/beta/unstable-book/the-unstable-book.html"&gt;the unstable book&lt;/a&gt;，这里会列出绝大部分。
Unstable book会连接到&lt;a href="https://github.com/rust-lang/rust/labels/C-tracking-issue"&gt;tracking issue&lt;/a&gt;，而后者往往会链接到&lt;a href="https://rust-lang.github.io/rfcs/"&gt;RFC&lt;/a&gt;。
组合使用这些来源，你可以很好地了解新特性。&lt;/p&gt;&lt;p&gt;Thank you for reading my first blog post 😃.
The best way to support me is by following my &lt;a href="https://twitter.com/efun_b"&gt;Twitter&lt;/a&gt;.
I am also looking for employment opportunities so please get in touch if you would like to talk about that.&lt;/p&gt;&lt;section class="footnotes"&gt;
&lt;ol&gt;
&lt;li id="fn-1"&gt;&lt;p&gt;&lt;a href="https://github.com/rust-lang/rust/issues/53120#issuecomment-1124065083"&gt;https://github.com/rust-lang/rust/issues/53120#issuecomment-1124065083&lt;/a&gt;&lt;a href="#fnref-1" class="footnote"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn-2"&gt;&lt;p&gt;&lt;a href="https://github.com/rust-lang/rust/issues/44580#issuecomment-1074040208"&gt;https://github.com/rust-lang/rust/issues/44580#issuecomment-1074040208&lt;/a&gt;&lt;a href="#fnref-2" class="footnote"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description><author>1348292515@qq.com (Poly000)</author><guid isPermaLink="true">/archives/awesome-unstable-rust-features/</guid><pubDate>Wed, 28 Jul 2021 15:04:00 +0806</pubDate></item><item><title>C23特性简介</title><link>/archives/c23-quickview/</link><description>&lt;h1&gt;差异&lt;/h1&gt;
&lt;h2&gt;移除&lt;/h2&gt;
&lt;h3&gt;数据类型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2的补码以外的有符号整数&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;语言特性&lt;/h3&gt;
&lt;h4&gt;K&amp;amp;R风格函数声明与定义&lt;/h4&gt;
&lt;p&gt;比如 &lt;code&gt;int main()&lt;/code&gt;，是经常被使用的旧式写法。&lt;/p&gt;&lt;p&gt;或者&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;add1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;不再允许&lt;code&gt;u&lt;/code&gt;/&lt;code&gt;U&lt;/code&gt;前缀的字符串字面量/字符常量为非UTF-16/32字符&lt;/li&gt;
&lt;li&gt;&lt;code&gt;__alignof_is_defined&lt;/code&gt; 和 &lt;code&gt;__alignas_is_defined&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;标准库&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;混合使用宽字符的连接&lt;/li&gt;
&lt;li&gt;对 &lt;code&gt;realloc()&lt;/code&gt; 传递0大小的调用（实现定义改为未定义）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;static_assert&lt;/code&gt;宏（改为关键字）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;thread_local&lt;/code&gt;宏（改为关键字）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;废弃&lt;/h2&gt;
&lt;h3&gt;标准库&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;stdnoreturn.h&amp;gt;&lt;/code&gt;，可使用 &lt;code&gt;[[noreturn]]标志&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;math.h&amp;gt;&lt;/code&gt; 定义的数值界限&lt;code&gt;INFINITY&lt;/code&gt;，&lt;code&gt;DEC_INFINITY&lt;/code&gt;，&lt;code&gt;NAN&lt;/code&gt;，&lt;code&gt;DEC_NAN&lt;/code&gt;（移动到 &lt;code&gt;&amp;lt;limits.h&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zh.cppreference.com/w/c/chrono/asctime"&gt;&lt;code&gt;asctime()&lt;/code&gt;&lt;/a&gt;，可使用 &lt;code&gt;asctime_s()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://zh.cppreference.com/w/c/chrono/ctime"&gt;&lt;code&gt;ctime()&lt;/code&gt;&lt;/a&gt;，可使用 &lt;code&gt;ctime_s()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;特性测试宏: &lt;code&gt;__STDC_IEC_559__&lt;/code&gt;，&lt;code&gt;__STDC_IEC_559_COMPLEX__&lt;/code&gt;，&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可使用&lt;code&gt;__STDC_IEC_60559_BFP__&lt;/code&gt;和&lt;code&gt;__STDC_IEC_559_COMPLEX__&lt;/code&gt;。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zh.cppreference.com/w/c/types/limits"&gt;&lt;code&gt;DECIMAL_DIG&lt;/code&gt;&lt;/a&gt;，序列化/反序列化&lt;code&gt;long double&lt;/code&gt;可能需要的十进制精度&lt;/li&gt;
&lt;li&gt;__bool_true_false_are_defeined （现在true/false都成了关键字）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;关键字&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;_Noreturn&lt;/code&gt; 函数限定符&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[[_Noreturn]]&lt;/code&gt; 属性&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;新增&lt;/h1&gt;
&lt;h2&gt;语言特性&lt;/h2&gt;
&lt;h3&gt;&lt;a href="https://zh.cppreference.com/w/c/language/attributes"&gt;属性 (attribute)&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;&lt;a href="https://en.cppreference.com/w/c/language/attributes/fallthrough"&gt;&lt;code&gt;[[fallthrough]]&lt;/code&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;表示从这里直落是有意的，编译器不应警告。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cond&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;A&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="n"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;fallthrough&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;B&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Error: ...&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;fallthrough&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;D&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="n"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;&lt;a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2956.htm"&gt;&lt;code&gt;[[unsequenced]]&lt;/code&gt;和&lt;code&gt;[[reproducible]]&lt;/code&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;[[unsequenced]]&lt;/code&gt; 要求函数无状态，无副作用，幂等，并且独立。&lt;/p&gt;&lt;p&gt;其中：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;无状态：没有定义可修改的静态或线程本地对象，也不调用有这种行为的函数。&lt;/li&gt;
&lt;li&gt;无副作用：没有可观测的副作用。&lt;/li&gt;
&lt;li&gt;幂等：重复的求值应当得到同样的结果。（可以读取全局状态）&lt;/li&gt;
&lt;li&gt;独立：不依赖参数和常量以外的状态（可以写入全局变量）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;[[reproducible]]&lt;/code&gt; 则只要求函数无副作用且幂等。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.cppreference.com/w/c/language/attributes/deprecated"&gt;&lt;code&gt;[[deprecated]]&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可通过&lt;code&gt;(&amp;quot;reason&amp;quot;)&lt;/code&gt;添加说明：&lt;code&gt;[[deprecated(&amp;quot;WTH are u using this&amp;quot;)]]&lt;/code&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.cppreference.com/w/c/language/attributes/maybe_unused"&gt;&lt;code&gt;[[maybe_unused]]&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;告诉编译器不要因为未使用警告。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.cppreference.com/w/c/language/attributes/nodiscard"&gt;&lt;code&gt;[[nodiscard]]&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;该类型/该函数的返回值不希望被直接丢弃。如错误信息，或者结果存储在返回值的函数。
可通过 &lt;code&gt;(&amp;quot;reason&amp;quot;)&lt;/code&gt;添加说明：&lt;code&gt;[[nodiscard(&amp;quot;Error info should be processed&amp;quot;)]]&lt;/code&gt;。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.cppreference.com/w/c/language/attributes/noreturn"&gt;&lt;code&gt;[[noreturn]]&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;该函数不通过return语句或达到底部返回。&lt;/p&gt;&lt;h3&gt;应用于数组的限定修饰符&lt;/h3&gt;
&lt;p&gt;数组类型和它的成员的类型现在被认为总是被同样地限定&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;_Atomic&lt;/code&gt;限定不可应用于数组。&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// OK until C23&lt;/span&gt;
&lt;span class="c1"&gt;// clang: cannot initialize a variable of type &amp;#39;int *&amp;#39; with an lvalue of type &amp;#39;const int[1]&amp;#39;&lt;/span&gt;
&lt;span class="c1"&gt;// Note clang will apply this rule even in C89-C17&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;关键字&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;前三项可被编译器为兼容性定义为宏&lt;/p&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;static_assert&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;thread_local&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;true&lt;/code&gt;, &lt;code&gt;false&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thephd.dev/c23-is-coming-here-is-what-is-on-the-menu#n3006--n3018---constexpr-for-object-definitions"&gt;&lt;code&gt;constexpr&lt;/code&gt;&lt;/a&gt; 存储周期修饰符/函数修饰符&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;预定义宏&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;不带message的 &lt;code&gt;_Static_assert&lt;/code&gt; 宏（现在应使用&lt;code&gt;static_assert&lt;/code&gt;关键字）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unreachable()&lt;/code&gt;，表示代码不可达。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdint.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stddef.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // size_t and not has unreachable()&lt;/span&gt;

&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;color&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;uint8_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// color_vec that works over pointer-to-array&lt;/span&gt;
&lt;span class="cp"&gt;#define VEC_TYPE color&lt;/span&gt;
&lt;span class="cp"&gt;#define VEC_NAME color_vec&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;vec.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;generate_texture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;p_texture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;square_wh&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;square_wh&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;fallthrough&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;fallthrough&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;color_vec_clear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_texture&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;color_vec_resize_init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_texture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;square_wh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;square_wh&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;unreachable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;数据类型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zh.cppreference.com/w/c/language/arithmetic_types"&gt;&lt;code&gt;十进制浮点类型&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;_Decimal32&lt;/code&gt;，&lt;code&gt;_Decimal64&lt;/code&gt; 以及 &lt;code&gt;_Decimal128&lt;/code&gt;。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;位精度整数，&lt;a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2763.pdf"&gt;&lt;code&gt;_BitInt(N)&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;二进制整数常量，以0b/0B前缀。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.cppreference.com/w/c/language/nullptr"&gt;nullptr&lt;/a&gt;常量和相关的&lt;a href="https://en.cppreference.com/w/c/types/nullptr_t"&gt;nullptr_t&lt;/a&gt;类型&lt;/li&gt;
&lt;li&gt;char16_t 和 char32_t 字符串字面量 &lt;a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2728.htm"&gt;必须是 UTF-16 和 UTF-32&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;字面量&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;u8&lt;/code&gt;前缀的 UTF-8 字符常量（u8'?'为单字节，u8&amp;quot;...&amp;quot; 为 &lt;code&gt;unsigned char [N]&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;数字分隔符 &lt;code&gt;'&lt;/code&gt;，如 114'514'1919L&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;预处理器指令&lt;/h3&gt;
&lt;h4&gt;&lt;a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2499.pdf"&gt;&lt;code&gt;#embed&lt;/code&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;icon_data&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// unsigned char为默认类型&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;#embed &amp;quot;art.png&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;#embed char &amp;quot;data.bin&amp;quot; &lt;/span&gt;&lt;span class="c1"&gt;// 其中char为类型名&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;qwq&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;#embed 32 &amp;quot;/dev/urandom&amp;quot; &lt;/span&gt;&lt;span class="c1"&gt;// 限制参数放在文件名之前；最多可以读入32字节。&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// 注意这是上界，并不意味着一定会读入这么多。&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;该资源的内容以实现定义的方式映射到数据中，它为每个元素使用 &lt;code&gt;CHAR_BIT * sizeof(type-name)&lt;/code&gt; 比特。如果该文件不足以多次填充这些位，则需要进行diagnostic。&lt;/p&gt;&lt;p&gt;其中类型名必须是基本整数类型。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;#elifdef&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#elifndef&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;#warning&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;其他&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zh.cppreference.com/w/c/language/initialization"&gt;空初始化&lt;/a&gt;器 &lt;code&gt;= {}&lt;/code&gt; 对于数组或自定义数据结构：对其成员空初始化；对于基本类型变量：对其本身空初始化。&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2480.pdf"&gt;函数定义中的不具名参数&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://open-std.org/JTC1/SC22/WG14/www/docs/n2508.pdf"&gt;声明或块结尾前的label&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2780.pdf"&gt;函数参数定义转发&lt;/a&gt;，可能在对ABI时需要使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;标准库特性&lt;/h2&gt;
&lt;h3&gt;现代的位运算工具&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://thephd.dev/c23-is-coming-here-is-what-is-on-the-menu#n3022---modern-bit-utilities"&gt;stdbit.h&lt;/a&gt;&lt;/p&gt;&lt;p&gt;有端序的宏和一些常见的位运算工具。&lt;/p&gt;&lt;h3&gt;printf()对整数的二进制格式化支持&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.open-std.org/jtc1/sc22/WG14/www/docs/n2630.pdf"&gt;标准&lt;/a&gt;&lt;/p&gt;&lt;p&gt;使用“%b”描述符输出整数为二进制。&lt;/p&gt;&lt;h3&gt;为格式化指定位长&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.open-std.org/Jtc1/sc22/WG14/www/docs/n2680.pdf"&gt;标准&lt;/a&gt;&lt;/p&gt;&lt;p&gt;当你想要输出一个很大的整数，之前的可移植做法是：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%jd&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;intmax_t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;some_integer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;但是 int128_t ， int256_t 得以支持后，我们也不能修改现存平台的 &lt;code&gt;intmax_t&lt;/code&gt; 定义。于是：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%w128d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;my_128b_integer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;你也可以指定打印该数字的低位：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%w8d&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mh"&gt;0x114&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;带溢出检查的整数运算&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2683.pdf"&gt;标准&lt;/a&gt;&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdckdint.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;ckd_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;ckd_sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;ckd_mul&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type2&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;type3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这三个函数支持任意内建整数类型。&lt;/p&gt;&lt;h2&gt;参考资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.cppreference.com/w/c/23"&gt;cppreference - c23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thephd.dev/c-the-improvements-june-september-virtual-c-meeting"&gt;C-ing the Improvement: Progress on C23&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thephd.dev/ever-closer-c23-improvements"&gt;Ever Closer - C23 Draws Nearer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thephd.dev/c23-is-coming-here-is-what-is-on-the-menu"&gt;C23 is Finished: Here is What is on the Menu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description><author>1348292515@qq.com (Poly000)</author><guid isPermaLink="true">/archives/c23-quickview/</guid><pubDate>Sat, 01 Oct 2022 17:38:00 +0806</pubDate></item><item><title>软RAID vs 硬RAID</title><link>/archives/software-raid-versus-hardware-raid/</link><description>&lt;h2&gt;Credit&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://utcc.utoronto.ca/~cks/space/blog/tech/HardwareVsSoftwareRAID"&gt;原文地址&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;正文&lt;/h2&gt;
&lt;p&gt;一个很容易引起争论的问题：硬RAID和软RAID哪个更快和（或）更好？&lt;/p&gt;&lt;p&gt;很多传统观点认为是硬RAID，但我很不同意。让我们问一个相反的问题：硬件RAID如何（或何时）比软件RAID快？&lt;/p&gt;&lt;p&gt;如果你要用RAID-5，硬件可以比你的CPU更快XOR。但是，在现代系统中，XOR的性能基本上受制于内存带宽，而不是CPU的能力。你可能有比CPU更好的内存带宽（显卡就是这样），但这并不便宜。&lt;/p&gt;&lt;p&gt;如果你要用RAID-1，硬件RAID可以减少写的总线带宽，从N个DMA传输到N个磁盘到一个DMA传输到自己。但是，为了使你的系统更快，你需要用写流量使PCI总线带宽饱和，这并不常见。(理论上，你也可以在RAID-5中遇到这种情况）。&lt;/p&gt;&lt;p&gt;就是这样。(欢迎补充和更正）&lt;/p&gt;&lt;p&gt;通常的反驳是，虽然硬件RAID可能不比软件RAID快，但至少把负荷从你的主CPU上转移了，所以系统的整体速度提高了。然而，要达到这种情况，你的系统需要在CPU方面很差，并且要做大量的写入IO（如果你的写入IO不是特别多，那么软RAID的额外CPU使用率也会很小）。这种情况也不太常见。&lt;/p&gt;&lt;p&gt;软件RAID有一个缺点：启动操作系统后才可以使用。这会使早期启动变得复杂。但软件RAID也有很多优点，如不依赖硬件。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;The one wildcard I can see in hardware RAID's favour is virtualization, which might deliver a future of heavily used hardware running close to both CPU and IO saturation.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;我认为虚拟化是硬RAID的优势所在，可以帮你压榨硬件，达到CPU和IO饱和。&lt;/p&gt;&lt;p&gt;DeepL翻译后润色。&lt;/p&gt;</description><author>1348292515@qq.com (Poly000)</author><guid isPermaLink="true">/archives/software-raid-versus-hardware-raid/</guid><pubDate>Fri, 24 Feb 2023 22:08:00 +0806</pubDate></item><item><title>Win32 盘符，设备号和硬盘型号</title><link>/archives/win32-drive-letters-deviceid-harddisk-model/</link><description>&lt;h2&gt;原发布地址&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/JonMagon/KDiskMark/issues/87#issuecomment-1925784750"&gt;原Issue评论&lt;/a&gt;，讨论 KDiskMark Windows 支持需要的工作&lt;/p&gt;&lt;h2&gt;列出设备&lt;/h2&gt;
&lt;h3&gt;逻辑设备&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getlogicaldrives"&gt;&lt;code&gt;GetLogicalDrives&lt;/code&gt;&lt;/a&gt; 会返回一组位码，值为1的位的位置加上'A'就是它代表的盘符&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;win32api&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GetLogicalDrives&lt;/span&gt;

&lt;span class="c1"&gt;# for example, `0b_1100` means there are C:/ and D:/.&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;logical_drives&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
   &lt;span class="n"&gt;bit_mask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetLogicalDrives&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="n"&gt;alphabet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;bit_mask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;alphabet&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;卷&lt;/h3&gt;
&lt;h4&gt;使用 Powershell&lt;sup class="footnote-ref" id="fnref-1"&gt;&lt;a href="#fn-1"&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;Get-Volume&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;使用 &lt;code&gt;mountvol.exe&lt;/code&gt;&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;mountvol /L
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用 &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstvolumew"&gt;&lt;code&gt;FindFirstVolumeW&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findnextvolumew"&gt;&lt;code&gt;FindNextVolumeW&lt;/code&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;winsys._kernel32&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FindFirstVolume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FindNextVolume&lt;/span&gt;
&lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FindFirstVolume&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;volumes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;FindNextVolume&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volume&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;获取硬盘型号&lt;/h2&gt;
&lt;h3&gt;盘符 -&amp;gt; 硬盘型号&lt;/h3&gt;
&lt;h4&gt;使用 Powershell&lt;sup class="footnote-ref" id="fnref-2"&gt;&lt;a href="#fn-2"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;Get-Disk&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Get-Partition&lt;/span&gt; &lt;span class="n"&gt;-DriveLetter&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;C&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;DiskNumber&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;select &lt;/span&gt;&lt;span class="n"&gt;-Prop&lt;/span&gt; &lt;span class="n"&gt;FriendlyName&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;盘符或任意卷 -&amp;gt; 设备号&lt;/h3&gt;
&lt;h4&gt;使用 Powershell （只支持盘符）&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Get-Partition&lt;/span&gt; &lt;span class="n"&gt;-DriveLetter&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;C&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;DiskNumber&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;使用 &lt;a href="https://learn.microsoft.com/en-US/windows/win32/api/winioctl/ni-winioctl-ioctl_storage_get_device_number"&gt;&lt;code&gt;IOCTL_STORAGE_GET_DEVICE_NUMBER&lt;/code&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;Windows.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;fileapi.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;winioctl.h&amp;gt;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;get_disk_number_by_drive_letter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;logical_drive_path&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logical_drive_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="se"&gt;\\\\&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s"&gt;%c:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// &amp;#39;\\?\Volume{&amp;lt;GUID&amp;gt;}&amp;#39; is also applicable to this&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;HANDLE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hDevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;CreateFileA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logical_drive_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GENERIC_READ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GENERIC_WRITE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILE_SHARE_READ&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;FILE_SHARE_WRITE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OPEN_EXISTING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hDevice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;INVALID_HANDLE_VALUE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Failed to open device. Error code: %lu&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GetLastError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;STORAGE_DEVICE_NUMBER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;DWORD&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bytes_returned&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;DeviceIoControl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hDevice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;IOCTL_STORAGE_GET_DEVICE_NUMBER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;bytes_returned&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;IOCTL_STORAGE_GET_DEVICE_NUMBER failed. Error code: %lu&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GetLastError&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;CloseHandle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hDevice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;CloseHandle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hDevice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;device_number&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeviceNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;设备号 -&amp;gt; 硬盘型号&lt;/h3&gt;
&lt;h4&gt;使用 Powershell&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;Get-Disk&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;select &lt;/span&gt;&lt;span class="n"&gt;-Prop&lt;/span&gt; &lt;span class="n"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;FriendlyName&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;使用 wmic&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;wmic diskdrive get index,model
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;使用 wmi&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;win32com.client&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GetObject&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;get_diskdrive_info&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;wmi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;winmgmts:&lt;/span&gt;&lt;span class="se"&gt;\\&lt;/span&gt;&lt;span class="s2"&gt;.\root\cimv2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;disks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wmi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExecQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SELECT * FROM Win32_DiskDrive&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;disk_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;disk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;disk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;disk&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;disks&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;disk_info&lt;/span&gt;

&lt;span class="n"&gt;disk_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_diskdrive_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;disk_info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Anyway, the most accurate way is to call &lt;code&gt;smartctl ... X:&lt;/code&gt;&lt;/p&gt;&lt;h2&gt;其他可能要用到的系统调用&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-querydosdevicew"&gt;&lt;code&gt;QueryDosDeviceW&lt;/code&gt;&lt;/a&gt; 可以用来从盘符获取卷编号（也可以用来列出卷，如果传入None），即 \Device\HarddiskVolume&lt;em&gt;X&lt;/em&gt; 中的 X 。&lt;/p&gt;&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdiskfreespaceexa"&gt;&lt;code&gt;GetDiskFreeSpaceExA&lt;/code&gt;&lt;/a&gt; 可以拿到对调用用户可用的空间（详见配额），总硬盘大小和总可用空间。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;win32file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;GetDiskFreeSpaceEx&lt;/span&gt;
&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;GetDiskFreeSpaceEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;C:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="c1"&gt;# [58.516212463378906, 117.97948837280273, 58.516212463378906]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;尾声&lt;/h2&gt;
&lt;p&gt;感谢&lt;sup class="footnote-ref" id="fnref-3"&gt;&lt;a href="#fn-3"&gt;3&lt;/a&gt;&lt;/sup&gt;的 Win32 Paths 解释&lt;/p&gt;&lt;section class="footnotes"&gt;
&lt;ol&gt;
&lt;li id="fn-1"&gt;&lt;p&gt;&lt;a href="https://winreg-kb.readthedocs.io/en/latest/sources/system-keys/Mounted-devices.html#notes"&gt;https://winreg-kb.readthedocs.io/en/latest/sources/system-keys/Mounted-devices.html#notes&lt;/a&gt;)&lt;a href="#fnref-1" class="footnote"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn-2"&gt;&lt;p&gt;&lt;a href="https://superuser.com/a/1147305"&gt;https://superuser.com/a/1147305&lt;/a&gt;&lt;a href="#fnref-2" class="footnote"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li id="fn-3"&gt;&lt;p&gt;&lt;a href="https://chrisdenton.github.io/omnipath/Overview.html"&gt;https://chrisdenton.github.io/omnipath/Overview.html&lt;/a&gt;&lt;a href="#fnref-3" class="footnote"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description><author>1348292515@qq.com (Poly000)</author><guid isPermaLink="true">/archives/win32-drive-letters-deviceid-harddisk-model/</guid><pubDate>Tue, 06 Feb 2024 18:23:00 +0806</pubDate></item><item><title>QEMU运行Windows启用安全启动</title><link>/archives/windows-qemu-guest-enable-secure-boot/</link><description>&lt;h2&gt;选项&lt;/h2&gt;
&lt;p&gt;从 Debian &lt;code&gt;ovmf&lt;/code&gt; 提取 &lt;code&gt;OVMF_VARS_4M.ms.fd&lt;/code&gt; &lt;sup class="footnote-ref" id="fnref-1"&gt;&lt;a href="#fn-1"&gt;1&lt;/a&gt;&lt;/sup&gt;，使用任意发行版提供的 &lt;code&gt;OVMF_CODE.secboot.4m.fd&lt;/code&gt; ：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;qemu&lt;span class="w"&gt; &lt;/span&gt;...&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-drive&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pflash,format&lt;span class="o"&gt;=&lt;/span&gt;raw,readonly&lt;span class="o"&gt;=&lt;/span&gt;on,file&lt;span class="o"&gt;=&lt;/span&gt;OVMF_CODE.fd&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-drive&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pflash,format&lt;span class="o"&gt;=&lt;/span&gt;raw,file&lt;span class="o"&gt;=&lt;/span&gt;OVMF_VARS.ms.fd&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;-machine&lt;span class="w"&gt; &lt;/span&gt;pc-q35-8.2
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中 &lt;code&gt;-machine&lt;/code&gt; 是指定一种支持 SecureBoot 的机器型号&lt;/p&gt;&lt;h2&gt;效果&lt;/h2&gt;
&lt;figure&gt;&lt;img loading="lazy" data-width="1280" data-height="808" src="/archives/assets/428f710d2914e276b14d58d8902424d9.jpg" alt="qemu-windows-sb" /&gt;&lt;figcaption&gt;qemu-windows-sb&lt;/figcaption&gt;&lt;/figure&gt;&lt;section class="footnotes"&gt;
&lt;ol&gt;
&lt;li id="fn-1"&gt;&lt;p&gt;&lt;a href="https://bbs.archlinux.org/viewtopic.php?id=275691"&gt;https://bbs.archlinux.org/viewtopic.php?id=275691&lt;/a&gt;&lt;a href="#fnref-1" class="footnote"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</description><author>1348292515@qq.com (Poly000)</author><guid isPermaLink="true">/archives/windows-qemu-guest-enable-secure-boot/</guid><pubDate>Thu, 07 Mar 2024 19:08:00 +0806</pubDate></item><item><title>Android 如何保持眼中存储干净</title><link>/archives/android-make-storage-clean/</link><description>&lt;h2&gt;&lt;a href="https://sr.rikka.app/zh-hans/"&gt;存储空间隔离&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;由 RikkaApps 开发。&lt;/p&gt;&lt;p&gt;由于基于目录重定向，垃圾文件实际上是放在了独立的空间&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;较为可控的目录限制&lt;/li&gt;
&lt;li&gt;可以阻止访问主用户隐私数据&lt;/li&gt;
&lt;li&gt;不同应用之间，无法基于内置存储中的垃圾文件追踪用户&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;付费闭源软件&lt;/li&gt;
&lt;li&gt;需要 Magisk/KernelSU/Xposed&lt;/li&gt;
&lt;li&gt;常年未更新，Android 14+ 支持未来堪忧&lt;/li&gt;
&lt;li&gt;非 Google Play 渠道购买，均为限制单手机使用&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href="https://github.com/MaterialCleaner/MaterialCleaner"&gt;MaterialCleaner&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;类似 &lt;a href="#%E5%AD%98%E5%82%A8%E7%A9%BA%E9%97%B4%E9%9A%94%E7%A6%BB"&gt;#存储空间隔离&lt;/a&gt;&lt;/p&gt;&lt;p&gt;这个项目被“酷安大神”搞死了，兼容性问题比较大&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.oasisfeng.island"&gt;IsLand&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;开发者同《绿色守护》&lt;/p&gt;&lt;p&gt;隔离环境，把国产软件塞一起；&lt;/p&gt;&lt;p&gt;基于Work Profile实现，国产ROM兼容性不一定好&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;也可用于反取证&lt;/li&gt;
&lt;li&gt;单空间使用，无需 Root&lt;/li&gt;
&lt;li&gt;可以阻止访问主用户隐私数据&lt;/li&gt;
&lt;li&gt;(root+放弃支付软件) 不同应用之间，无法基于内置存储中的垃圾文件追踪用户&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;新版本转为闭源软件&lt;/li&gt;
&lt;li&gt;需要Root才能开启多个工作资料，互相隔离不同国产应用&lt;/li&gt;
&lt;li&gt;输入法、支付应用调用都是分割的，这一点会影响上一条&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href="https://secure-system.gitlab.io/Insular/"&gt;Insular&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="#island"&gt;#IsLand&lt;/a&gt; 的开源复刻实现。&lt;/p&gt;&lt;/blockquote&gt;
&lt;h2&gt;&lt;a href="https://github.com/Petit-Abba/black_and_white_list"&gt;black_and_white_list&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;代码质量极差，但是目前没人写类似的打包了的东西&lt;/p&gt;&lt;p&gt;定期清理，最原始的方式&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;较为灵活&lt;/li&gt;
&lt;li&gt;提供了白名单，避免误删&lt;/li&gt;
&lt;li&gt;应用无关，单纯写路径规则&lt;/li&gt;
&lt;li&gt;不同应用之间，无法基于内置存储中的垃圾文件追踪用户&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;久年未更&lt;/li&gt;
&lt;li&gt;未提供图形化设置方式&lt;/li&gt;
&lt;li&gt;配置文件为未知文本解析方式&lt;/li&gt;
&lt;li&gt;依赖 Magisk 和大量不规范行为&lt;/li&gt;
&lt;li&gt;基于 crond ，古老的定时服务方式&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;a href="https://github.com/mokurin000/garbage-remove"&gt;garbage-remove&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Rust实现&lt;/p&gt;&lt;p&gt;同样是定期清理&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;无需Root&lt;/li&gt;
&lt;li&gt;高性能，高可读日志&lt;/li&gt;
&lt;li&gt;配置文件为 toml 格式&lt;/li&gt;
&lt;li&gt;默认不允许删除相对路径&lt;/li&gt;
&lt;li&gt;不同应用之间，无法基于内置存储中的垃圾文件追踪用户&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;未提供图形化设置方式&lt;/li&gt;
&lt;li&gt;过度优化的实现，使用mpmc+多线程删除&lt;/li&gt;
&lt;li&gt;未提供模块服务方式运行，需要手动保活&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;买台 iPhone 备用机&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;终极方案，长久有效&lt;/p&gt;&lt;/blockquote&gt;
&lt;h3&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;隐私保护最好的方式&lt;/li&gt;
&lt;li&gt;省心，不会遇到各种风控过不去&lt;/li&gt;
&lt;li&gt;环境物理隔离，不再担心侧漏检测&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;成本较高&lt;/li&gt;
&lt;/ul&gt;
</description><author>1348292515@qq.com (Poly000)</author><guid isPermaLink="true">/archives/android-make-storage-clean/</guid><pubDate>Thu, 28 Nov 2024 13:27:00 +0806</pubDate></item><item><title>基于 Xiu 和 ffmpeg 的局域网录像机平替方案</title><link>/archives/xiu-ffmpeg-based-lan-video-recorder/</link><description>&lt;h1&gt;硬件需要&lt;/h1&gt;
&lt;h2&gt;路由器/无线光猫&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;需要可以绑定 MAC 到 LAN IP&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;摄像头&lt;/h2&gt;
&lt;h3&gt;丐版 (本教程)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;一部可以长期供电、固定录制的手机&lt;blockquote&gt;
如果充电不够稳定，可能会出现 ffmpeg 在手机重启、重新开始推送服务后仍然挂起的状态

考虑为 ffmpeg 对应服务设置 RuntimeMaxSec 来减少空白期&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;一台 10w-20w 功率的LED灯，提供手动补光（一体式约15~20 CNY）&lt;/li&gt;
&lt;li&gt;一根足够稳定，不会摔坏你手机的摄像支架&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;家庭版&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;听闻只有乐橙的网络摄像机不是云存储服务的副产品,
包括 rtsp流/ONVIF 都是公开的。&lt;/p&gt;&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;一台乐橙网络摄像机，需支持接入你的局域网&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;企业方案&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;一台专业的，包含 RTSP 协议透明引出的“企业用”溢价的业内品牌网络摄像机&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;录像机&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;一台可以长期供电，带有停电时自动关机（你的笔记本电池，何尝不是UPS？）的电脑&lt;ul&gt;
&lt;li&gt;最好带有可用的硬件视频编码支持。&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
本教程只考虑了 intel QuickSyncVideo / NVIDIA NVENC
可以自行调整 AMD 支持参数&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;软件需要&lt;/h1&gt;
&lt;h2&gt;摄像手机&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://apt.izzysoft.de/fdroid/index/apk/com.spynet.camtest"&gt;SpyNET Camera&lt;/a&gt;，开源软件，2017停更&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.pas.webcam"&gt;IP摄像头&lt;/a&gt;，广告软件&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;录像机&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;运行有 Systemd-based 发行版，或 Windows（自行使用 &lt;a href="https://nssm.cc/"&gt;nssm&lt;/a&gt; 管理服务）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Xiu 配置文件&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;nano&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/xiu.toml
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;[rtmp]&lt;/span&gt;
&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1935&lt;/span&gt;
&lt;span class="n"&gt;gop&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="k"&gt;[hls]&lt;/span&gt;
&lt;span class="n"&gt;enabled&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;
&lt;span class="n"&gt;need_record&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="k"&gt;[authsecret]&lt;/span&gt;
&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;ffmpeg 推流+时间戳脚本&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;此处以 nushell 为例，你可以把它改写成 bash 脚本等&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;nano&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/rtsp-to-rtmp.nu
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;QuickSync&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/nu

# 填入你的 RTSP 推流地址
let rtsp_addr = &amp;quot;rtsp://192.168.xxx.xxx:8080/h264.sdp&amp;quot;;
# 填入你的摄像头名称
let camera_prefix = &amp;quot;&amp;quot;;

(
  ffmpeg
  -rtsp_transport tcp # 指定TCP协议
  -hwaccel qsv # QuickSyncVideo 加速
  -i $rtsp_addr -framerate 30 # 30 fps
  -c:v h264_qsv -global_quality 30 # ICQ 30
  -f flv -ar 22050 # 音频采样率
  ( &amp;quot;rtmp://127.0.0.1/live/&amp;quot; + $camera_prefix + ( date now | format date &amp;quot;%Y-%m-%d_%H-%M-%S&amp;quot; ))
)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;NVENC&lt;/h4&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/nu

# 填入你的 RTSP 推流地址
let rtsp_addr = &amp;quot;rtsp://192.168.xxx.xxx:8080/h264.sdp&amp;quot;;
# 填入你的摄像头名称
let camera_prefix = &amp;quot;&amp;quot;;

(
  ffmpeg
  -rtsp_transport tcp # 指定TCP协议
  -hwaccel cuda # CUDA加速
  -i $rtsp_addr -framerate 30 # 30 fps
  -c:v h264_nvenc -rc:v vbr_hq -cq 30 # CQR 30
  -f flv -ar 22050 # 音频采样率
  ( &amp;quot;rtmp://127.0.0.1/live/&amp;quot; + $camera_prefix + ( date now | format date &amp;quot;%Y-%m-%d_%H_%M_%S&amp;quot; ))
)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Systemd 服务项&lt;/h3&gt;
&lt;h4&gt;建立目录&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;~/.local/share/systemd/user
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Xiu&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;nano&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/.local/share/systemd/user/xiu.service
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Xiu Service&lt;/span&gt;
&lt;span class="na"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network-manager.service&lt;/span&gt;

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="c1"&gt;# user 改为你的用户名&lt;/span&gt;
&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/xiu -c /home/user/xiu.toml&lt;/span&gt;
&lt;span class="c1"&gt;# 此目录为存储 ./live/&amp;lt;时间戳&amp;gt;/*.{ts,m3u8} 的目录&lt;/span&gt;
&lt;span class="na"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/mnt/Data/monitor&lt;/span&gt;
&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default.target&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;--now&lt;span class="w"&gt; &lt;/span&gt;xiu.service
&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;FFmpeg 转发流&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;nano&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;~/.local/share/systemd/user/rtmp-to-rtsp.service
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;RTSP Push to RTMP Service&lt;/span&gt;
&lt;span class="na"&gt;After&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network-manager.service&lt;/span&gt;

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="c1"&gt;# user 改为你的用户名&lt;/span&gt;
&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/home/user/rtsp_push_rtmp.nu&lt;/span&gt;
&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="c1"&gt;# 每小时分一次 vod_[...].m3u8&lt;/span&gt;
&lt;span class="na"&gt;RuntimeMaxSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;3600&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;default.target&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--user&lt;span class="w"&gt; &lt;/span&gt;--now&lt;span class="w"&gt; &lt;/span&gt;rtmp-to-rtsp.service
&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;tmpfiles.d 清理视频录像&lt;/h3&gt;
&lt;p&gt;例如，清理三天前创建的目录/文件:&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;e /path/to/live 0755 用户名 用户名 cC:3d -
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;注意，cC分别表示文件和目录的创建时间，不添加 cC: 会导致默认考虑访问时间。&lt;/p&gt;&lt;h1&gt;尾声&lt;/h1&gt;
&lt;p&gt;现在 &lt;code&gt;xiu&lt;/code&gt; 就可以在你设置好的存储位置自动产出动态 &lt;code&gt;.m3u8&lt;/code&gt; 文件和（每当 Xiu退出/串流停止推往Xiu 时生成）的总 &lt;code&gt;vod_&amp;lt;...&amp;gt;.m3u8&lt;/code&gt; 。&lt;/p&gt;&lt;p&gt;使用以下命令将 H264 编码的 &lt;code&gt;*.ts&lt;/code&gt; 文件合并为 &lt;code&gt;.mp4&lt;/code&gt; 格式，以使 mpv 可以正常seek视频。&lt;/p&gt;&lt;p&gt;使用 nushell 脚本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 此处改为你的视频存储路径
cd /path/to/live

for $it in (fd '^vod_.*\.m3u8$' | lines) {
    # 提取文件名部分，这里是配合产生的 `&amp;lt;时间戳&amp;gt;/vod_&amp;lt;时间戳&amp;gt;.m3u8` 路径格式
    let name = ($it | str replace --regex &amp;quot;/.*&amp;quot; &amp;quot;&amp;quot;);

    # 合并 .m3u8 视频，不进行重编码
    ffmpeg -i $it -codec copy ($name + &amp;quot;.mp4&amp;quot;)

    # 清理合并成功的 .ts 视频分片
    if ($env.LAST_EXIT_CODE == 0) {
        rm -rf $name
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;播放视频时，可以直接使用NuShell脚本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let prefix = &amp;quot;&amp;quot;;
let output = $prefix + &amp;quot;temp.m3u&amp;quot;;

# 此处可以自行填写年份，月份，日期，小时等
let pattern = '^' + $prefix + '....-..-.._.._.._..\.mp4$';

fd $pattern out&amp;gt; $output
mpv $output
&lt;/code&gt;&lt;/pre&gt;
</description><author>1348292515@qq.com (Poly000)</author><guid isPermaLink="true">/archives/xiu-ffmpeg-based-lan-video-recorder/</guid><pubDate>Fri, 21 Feb 2025 13:07:00 +0806</pubDate></item><item><title>HN8145XR光猫-河南移动-资料整理</title><link>/archives/fuck-wuawei-hn8145xr/</link><description>&lt;h1&gt;前言&lt;/h1&gt;
&lt;p&gt;本人有幸用上了 河南移动 网络接入，我们井盖省的网络封闭程度一直是内地省份中数一数二。&lt;/p&gt;&lt;p&gt;相关软件会放在 &lt;a href="https://github.com/mokurin000/fuck-wuawei-modem"&gt;fuck-wuawei-modem&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;还原可用的Shell环境&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;来源: &lt;a href="https://www.right.com.cn/forum/thread-8339357-1-1.html"&gt;分享HN8145XR开telnet及补全shell个人心得&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Telnet用户：root
Telnet密码：&lt;code&gt;adminHW&lt;/code&gt;, &lt;code&gt;Hw8@cMcc&lt;/code&gt; 等&lt;/p&gt;&lt;/blockquote&gt;
&lt;ol start="0"&gt;
&lt;li&gt;启动 &lt;code&gt;ONT_telnet_enable.exe&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;网线连接光猫和电脑/笔记本&lt;/li&gt;
&lt;li&gt;打开使能工具，选择对应有线网卡，展开设备列表&lt;/li&gt;
&lt;li&gt;断开光猫电源&lt;/li&gt;
&lt;li&gt;选择“V5使能”，点击启动&lt;/li&gt;
&lt;li&gt;恢复光猫电源，等待出现“Failed”字样，不用管；待到光猫LED灯全部熄灭，点击停止。不要退出使能工具&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;此处可以检查 telnet 是否已经可以连接。&lt;/p&gt;&lt;/blockquote&gt;
&lt;ol start="6"&gt;
&lt;li&gt;选择“升级”，版本包选择 &lt;code&gt;shell9.bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;点击开始，再次重启光猫电源&lt;/li&gt;
&lt;li&gt;等待光猫LED再次全部熄灭（除下行光），出现 “Failed” ，点击停止，退出使能工具。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;基于Telnet获取超管密码&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;参考：&lt;a href="https://www.silencetime.com/index.php/archives/359/"&gt;通过telnet取得华为HN8145XR超级密码&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;telnet&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.1.1
&lt;span class="c1"&gt;# -&amp;gt; root&lt;/span&gt;
&lt;span class="c1"&gt;# -&amp;gt; (telnet密码)&lt;/span&gt;
su
shell
&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/mnt/jffs2/
cp&lt;span class="w"&gt; &lt;/span&gt;hw_ctree.xml&lt;span class="w"&gt; &lt;/span&gt;myconf.xml.gz
aescrypt2&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;myconf.xml.gz&lt;span class="w"&gt; &lt;/span&gt;tmp&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# 此处tmp被忽略了&lt;/span&gt;
zcat&lt;span class="w"&gt; &lt;/span&gt;myconf.xml.gz&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;grep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;UserName=&amp;quot;CMCCAdmin&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;cut&lt;span class="w"&gt; &lt;/span&gt;-d&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以得到如下结果：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Password=&amp;quot;$2...............$&amp;quot;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;使用 &lt;code&gt;WW_Dollar2.exe&lt;/code&gt; ，点击计算，可以解密 $2 密文。&lt;/p&gt;&lt;p&gt;得到的密文可以需要拼接上 &lt;code&gt;CMCCAdmin&lt;/code&gt; / &lt;code&gt;CMCCAdmin#&lt;/code&gt; ，如果是中国移动版&lt;/p&gt;&lt;p&gt;作者这里得到了一串sha256sum (-_-||| ) 还好是电话要的密码&lt;/p&gt;&lt;p&gt;考虑到河南移动的做法是 CMCCAdmin + 八位随机字符，目前时代个人算力暂不可能爆破。&lt;/p&gt;&lt;h2&gt;从hash后的宽带密码/超级密码计算原密码&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;来源：PurePeace 的 &lt;a href="https://blog.csdn.net/qq_26373925/article/details/112798210"&gt;获取移动光猫（如HS8545M5等设备）pppoe密码明文&lt;/a&gt;，略有修改&lt;/p&gt;&lt;p&gt;Rust写了&lt;a href="https://github.com/mokurin000/hw-hash-bruteforce"&gt;一份&lt;/a&gt;，可以用来试试看更长的密码
另外，移动似乎倾向于设置为手机号后六位。&lt;/p&gt;&lt;p&gt;更建议的方式：通过手机营业厅重置密码，获取新的 PPPoE 拨号密码
移动可以发送 &lt;code&gt;CZKDMM&lt;/code&gt; 到 10086，&lt;a href="sms:+10086?&amp;amp;body=CZKDMM"&gt;发送短信&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;sys&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nn"&gt;hashlib&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hashlib&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;find_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# 生成六位密码&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;06&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;IndexError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Usage:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;    &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;lt;sha256hashsecret&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;恢复华为公版界面&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;参考：&lt;a href="https://www.chinadsl.net/thread-172911-1-1.html"&gt;折腾HN8145XR（恢复华为界面 等）&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;需要先备份好 宽带帐户，宽带密码，ONT认证密码&lt;/p&gt;&lt;p&gt;如果只修改界面，不直接 restore_xxx.sh ，可能可以保留下来ONT认证密码&lt;/p&gt;&lt;p&gt;作者的OTN注册方式是 Password&lt;/p&gt;&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;启动 &lt;code&gt;WW_Dollar2.exe&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在你的电脑启动 ncat:&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;如果没有ncat，可以 &lt;code&gt;scoop install nmap&lt;/code&gt;。&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ncat&lt;span class="w"&gt; &lt;/span&gt;-l&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9999&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;hw_boardinfo
&lt;/pre&gt;&lt;/div&gt;
&lt;ol start="3"&gt;
&lt;li&gt;在光猫，使用 busybox nc 把 hw_boardinfo 传过来：&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;此处 192.168.1.4 为电脑的局域网IP&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;busybox&lt;span class="w"&gt; &lt;/span&gt;nc&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;192&lt;/span&gt;.168.1.4&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;9999&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&amp;lt;&lt;span class="w"&gt; &lt;/span&gt;/mnt/jffs2/hw_boardinfo
&lt;/pre&gt;&lt;/div&gt;
&lt;ol start="4"&gt;
&lt;li&gt;备份一份 &lt;code&gt;hw_boardinfo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;打开 &lt;code&gt;hw_boardinfo&lt;/code&gt; ，修改：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;obj.id = &amp;quot;0x0000001a&amp;quot;; obj.value = &amp;quot;COMMON&amp;quot;;
obj.id = &amp;quot;0x0000001b&amp;quot;; obj.value = &amp;quot;COMMON&amp;quot;;
obj.id = &amp;quot;0x00000031&amp;quot;; obj.value = &amp;quot;NOCHOOSE&amp;quot;;
&lt;/pre&gt;&lt;/div&gt;
&lt;ol start="6"&gt;
&lt;li&gt;把修改后的 hw_boardinfo 传回覆盖 &lt;code&gt;/mnt/jffs2/hw_boardinfo&lt;/code&gt; 和 &lt;code&gt;/mnt/jffs2/hw_boardinfo.bak&lt;/code&gt; 。&lt;/li&gt;
&lt;/ol&gt;
</description><author>1348292515@qq.com (Poly000)</author><guid isPermaLink="true">/archives/fuck-wuawei-hn8145xr/</guid><pubDate>Wed, 26 Feb 2025 11:30:00 +0806</pubDate></item><item><title>Frigate + NVIDIA 显卡笔记本的部署</title><link>/archives/frigate-on-linux-laptop-with-nvidia/</link><description>&lt;h2&gt;软件前置&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo&lt;span class="w"&gt; &lt;/span&gt;pacman&lt;span class="w"&gt; &lt;/span&gt;-Syu&lt;span class="w"&gt; &lt;/span&gt;docker&lt;span class="w"&gt; &lt;/span&gt;docker-compose&lt;span class="w"&gt; &lt;/span&gt;nvidia-container-toolkit
sudo&lt;span class="w"&gt; &lt;/span&gt;systemctl&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;enable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;--now&lt;span class="w"&gt; &lt;/span&gt;docker
&lt;span class="c1"&gt;# 确保 docker0 已经被代理或已设置好连接代理&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;硬件要求&lt;/h2&gt;
&lt;p&gt;该方案相比于之前的丐版方案，需要更新的硬件才能解决种种兼容或性能问题。&lt;/p&gt;&lt;p&gt;笔者测试的环境：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;-`
                  .o+`
                 `ooo/
                `+oooo:
               `+oooooo:                 poly@mokurin-arch 
               -+oooooo+:                ----------------- 
             `/:-:++oooo+:               OS: Arch Linux x86_64 
            `/++++/+++++++:              Host: Dell G15 5520 
           `/++++++++++++++:             Kernel: 6.15.2-arch1-1 
          `/+++ooooooooooooo/`           Uptime: 22 hours, 2 mins 
         ./ooosssso++osssssso+`          Packages: 2766 (pacman), 8 (flatpak) 
        .oossssso-````/ossssss+`         Shell: zsh 5.9 
       -osssssso.      :ssssssso.        Resolution: 1920x1080 
      :osssssss/        osssso+++.       DE: Plasma 6.3.5 
     /ossssssss/        +ssssooo/-       WM: kwin 
   `/ossssso+/:-        -:/+osssso+-     Theme: Materia [GTK2/3] 
  `+sso+:-`                 `.-/+oso:    Icons: breeze-dark [GTK2/3] 
 `++:.                           `-/+/   Terminal: vscode 
 .`                                 `/   CPU: 12th Gen Intel i7-12700H (20) @ 4.600GHz 
                                         GPU: Intel Alder Lake-P GT2 [Iris Xe Graphics] 
                                         GPU: NVIDIA GeForce RTX 3060 Mobile / Max-Q 
                                         Memory: -- MiB / 15669MiB
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;使用的文件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;init.sh&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;storage
mkdir&lt;span class="w"&gt; &lt;/span&gt;-p&lt;span class="w"&gt; &lt;/span&gt;config/model_cache/jinaai/jina-clip-v1
&lt;span class="c1"&gt;# btrfs 改善 sqlite 的性能&lt;/span&gt;
chattr&lt;span class="w"&gt; &lt;/span&gt;-R&lt;span class="w"&gt; &lt;/span&gt;+C&lt;span class="w"&gt; &lt;/span&gt;config&lt;span class="w"&gt; &lt;/span&gt;storage
cp&lt;span class="w"&gt; &lt;/span&gt;--reflink&lt;span class="o"&gt;=&lt;/span&gt;auto&lt;span class="w"&gt; &lt;/span&gt;config.yaml&lt;span class="w"&gt; &lt;/span&gt;config/
cp&lt;span class="w"&gt; &lt;/span&gt;--reflink&lt;span class="o"&gt;=&lt;/span&gt;auto&lt;span class="w"&gt; &lt;/span&gt;yolo_nas_s.onnx&lt;span class="w"&gt; &lt;/span&gt;config/

&lt;span class="c1"&gt;# optional, useless semantic search&lt;/span&gt;
&lt;span class="c1"&gt;# cp --reflink=auto *_fp16.onnx config/model_cache/jinaai/jina-clip-v1/&lt;/span&gt;

docker-compose&lt;span class="w"&gt; &lt;/span&gt;up&lt;span class="w"&gt; &lt;/span&gt;-d
&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;yolo_nas_s.onnx&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;该文件由于禁止分发转换模型，建议使用 &lt;a href="https://colab.research.google.com/github/blakeblackshear/frigate/blob/dev/notebooks/YOLO_NAS_Pretrained_Export.ipynb"&gt;colab&lt;/a&gt; 运行获取。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;-tensorrt&lt;/code&gt; 只有用N卡加速才需要，AMD / Intel 卡不需要。&lt;/p&gt;&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;frigate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;frigate&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;unless-stopped&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;stop_grace_period&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;30s&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ghcr.io/blakeblackshear/frigate:stable-tensorrt&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;./config:/config&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;./storage:/media/frigate&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;tmpfs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# Optional: 1GB of memory, reduces SSD/SD Card wear&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;/tmp/cache&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;tmpfs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;1000000000&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;cap_add&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;CAP_PERFMON&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;8971:8971&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;8554:8554&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# RTSP feeds&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;nvidia&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# migrate to CDI for newest nvidia driver&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;deploy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nt"&gt;reservations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;devices&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;nvidia&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;device_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class="p p-Indicator"&gt;]&lt;/span&gt;
&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="nt"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p p-Indicator"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;gpu&lt;/span&gt;&lt;span class="p p-Indicator"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;video&lt;/span&gt;&lt;span class="p p-Indicator"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;config.yaml&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;此处以乐橙为例子。大多摄像头可以在 iSpy 的文档找到需要的链接。&lt;/p&gt;&lt;p&gt;顺便一提，乐橙摄像头要求 WIFI 密码必须是字母加数字，否则不可能连接成功。&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;frigate 在这方面的文档出奇的烂。你需要综合翻阅 &lt;a href="https://docs.frigate.video/configuration/reference/"&gt;完整参考配置&lt;/a&gt; 和小节甚至 issues 。&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;0.15-1&lt;/span&gt;
&lt;span class="c1"&gt;# 关闭 mqtt 消息队列&lt;/span&gt;
&lt;span class="nt"&gt;mqtt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;false&lt;/span&gt;
&lt;span class="c1"&gt;# 关闭 TLS 连接（端口不变）&lt;/span&gt;
&lt;span class="nt"&gt;tls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;false&lt;/span&gt;
&lt;span class="c1"&gt;# 关闭网页验证&lt;/span&gt;
&lt;span class="nt"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# 如果启用，admin密码会在首次启动时输出到日志。&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# 错过了没关系，看 `docker-compose logs` 输出。&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;false&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;

&lt;span class="nt"&gt;ffmpeg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# 如果遇到 hardware capacity xxxx 问题，&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# 可以通过官方工具设置使用 H264 编码传输。&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# 如 乐橙: https://www.imou.com/en/support/download&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;hwaccel_args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;preset-nvidia&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# IMOU 的摄像头rtsp流，udp传输时很容易丢包、重复包、断流。&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;input_args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;-rtsp_transport tcp&lt;/span&gt;


&lt;span class="c1"&gt;# 保留录制历史，1天的全部视频和30天的警告/识别片段。&lt;/span&gt;
&lt;span class="nt"&gt;record&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;true&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;retain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;days&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;1&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;all&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;alerts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;retain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;days&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;30&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;motion&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;detections&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;retain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;days&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;30&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;motion&lt;/span&gt;

&lt;span class="nt"&gt;cameras&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;backyard&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;true&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;ffmpeg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;# 此处 PASSWORD 和乐橙 app 中设置的一致。&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="c1"&gt;# CAMIP 即为你的摄像头绑定的 ip 地址。&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;rtsp://admin:PASSWORD@CAMIP:554/cam/realmonitor?channel=1&amp;amp;subtype=0&lt;/span&gt;
&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="nt"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;detect&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;detect&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;true&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# 上下左右。请勿尝试通过 onvif 启用 autotracking ，乐橙这种情况会死机。&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;onvif&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;CAMIP&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;80&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;admin&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;PASSWORD&lt;/span&gt;


&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;motion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="c1"&gt;# mask掉乐橙的时间戳区域。&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;mask&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;0.015,0.041,0.268,0.041,0.267,0.086,0.014,0.089&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;40&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# 减少树叶抖动导致的不必要 detect。&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;contour_area&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;10&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nt"&gt;improve_contrast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;true&lt;/span&gt;

&lt;span class="c1"&gt;# 注意：部分旧版显卡可能会遇到 onnxruntime 不支持对应 kernel 版本的问题&lt;/span&gt;
&lt;span class="c1"&gt;# 如果有 Intel CPU 可以考虑 OpenVINO - CPU 运行。&lt;/span&gt;
&lt;span class="nt"&gt;detectors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;onnx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;onnx&lt;/span&gt;

&lt;span class="c1"&gt;# 此处识别高宽和之前 ipynb 运行时设置一致。&lt;/span&gt;
&lt;span class="nt"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;model_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;yolonas&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;320&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# &amp;lt;--- should match whatever was set in notebook&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;320&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# &amp;lt;--- should match whatever was set in notebook&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;input_pixel_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;bgr&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;input_tensor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;nchw&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;/config/yolo_nas_s.onnx&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;labelmap_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;/labelmap/coco-80.txt&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;如何彻底关闭服务&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;docker-compose&lt;span class="w"&gt; &lt;/span&gt;down
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;如何通过命令行重启服务 (不推荐)&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;docker-compose&lt;span class="w"&gt; &lt;/span&gt;stop
sleep&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
docker-compose&lt;span class="w"&gt; &lt;/span&gt;start
&lt;/pre&gt;&lt;/div&gt;
</description><author>1348292515@qq.com (Poly000)</author><guid isPermaLink="true">/archives/frigate-on-linux-laptop-with-nvidia/</guid><pubDate>Mon, 18 Aug 2025 12:22:00 +0806</pubDate></item><item><title>远程桌面控制软件-二开</title><link>/archives/remote-desktop-make-in-1-day/</link><description>&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;该博文会收录一些关于某远程软件二次开发需要的操作，请大家修改后遵循 GPLv3 要求！&lt;/p&gt;&lt;h2&gt;官方高级设置&lt;/h2&gt;
&lt;p&gt;官方的高级设置均可以对应到 &lt;code&gt;hbb_common::config::keys::OPTION_&lt;/code&gt; 系列变量&lt;/p&gt;&lt;h2&gt;hide-tray&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;src/tray.rs::start_tray&lt;/code&gt; 负责启动托盘图标，其在 macos 会强要求托盘图标启动&lt;/p&gt;&lt;h2&gt;s/RustDesk/XXXXDesk&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;# 写死在一些翻译中
src/lang.rs
 -&amp;gt; translate_locale
    - 此处的 s.replace 会判断 upgrade_rustdesk_server_pro* 和
      powered_by_me 两个特殊字段，需要修改 APP_NAME 才会判定需要替换。
# 程序 App name
libs/hbb_common
 -&amp;gt; src/config.rs
    - APP_NAME
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;替换服务器&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;libs/hbb_common
 -&amp;gt; src/config.rs
    - RENDEZVOUS_SERVERS
    - RS_PUB_KEY
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;固定密码&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;libs/hbb_common
 -&amp;gt; src/config.rs
    - get_permanent_password
&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;免安装启动器&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;注意：修改图标后可能由于 Windows 资源管理器图标缓存而仍显示为原本图标&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Runner 本身的其他信息：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;flutter/windows/runner/Runner.rc
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;使用 &lt;code&gt;libs/portable&lt;/code&gt; 前需要放入 &lt;code&gt;Runner.res&lt;/code&gt; ，res中的图标会被它的 &lt;code&gt;build.rs&lt;/code&gt; 忽略。&lt;/p&gt;&lt;p&gt;Runner 和本体的图标：&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;res/icon.ico
flutter/windows/runner/resources/app_icon.ico
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;打包时，&lt;/p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# 包含 flutter runtime, 打印机驱动等, librustdesk.{dll,dylib,so} 的文件夹&lt;/span&gt;
&lt;span class="nv"&gt;build_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;...
python3&lt;span class="w"&gt; &lt;/span&gt;./generate.py&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;../../&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;build_dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/&lt;span class="w"&gt; &lt;/span&gt;-o&lt;span class="w"&gt; &lt;/span&gt;.&lt;span class="w"&gt; &lt;/span&gt;-e&lt;span class="w"&gt; &lt;/span&gt;../../&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;build_dir&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;/XXXXDesk.exe
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;或者于CI中移除 &lt;code&gt;skip_portable_pack&lt;/code&gt; 。&lt;/p&gt;&lt;h2&gt;输入事件&lt;/h2&gt;
&lt;p&gt;Rustdesk 有多种不同输入方式，其中 &lt;code&gt;LegacyMode&lt;/code&gt; 全权使用 &lt;code&gt;enigo&lt;/code&gt;，翻译和 1:1 模式则混合使用 &lt;code&gt;enigo&lt;/code&gt; 或 &lt;code&gt;rdev&lt;/code&gt;。&lt;/p&gt;&lt;p&gt;顺带一提，Linux 平台下，Rustdesk 可能会启动输入服务并且通过IPC发送输入按键。&lt;/p&gt;&lt;p&gt;&lt;code&gt;src/ui_session_interface.rs&lt;/code&gt; 中， &lt;code&gt;get_keyboard_mode&lt;/code&gt; 负责返回会话使用的键盘模式。&lt;/p&gt;</description><author>1348292515@qq.com (mokurin000)</author><guid isPermaLink="true">/archives/remote-desktop-make-in-1-day/</guid><pubDate>Sat, 03 Jan 2026 14:00:00 +0806</pubDate></item></channel></rss>