You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

300 lines
17 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE HTML>
<html lang="zh-CN" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>1.80 - Rust语言圣经(Rust Course)</title>
<!-- Custom HTML head -->
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="../../favicon.svg">
<link rel="shortcut icon" href="../../favicon.png">
<link rel="stylesheet" href="../../css/variables.css">
<link rel="stylesheet" href="../../css/general.css">
<link rel="stylesheet" href="../../css/chrome.css">
<link rel="stylesheet" href="../../css/print.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="../../FontAwesome/css/font-awesome.css">
<link rel="stylesheet" href="../../fonts/fonts.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="highlight-css" href="../../highlight.css">
<link rel="stylesheet" id="tomorrow-night-css" href="../../tomorrow-night.css">
<link rel="stylesheet" id="ayu-highlight-css" href="../../ayu-highlight.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="../../theme/style.css">
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "../../";
const default_light_theme = "light";
const default_dark_theme = "navy";
</script>
<!-- Start loading toc.js asap -->
<script src="../../toc.js"></script>
</head>
<body>
<div id="body-container">
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script>
try {
let theme = localStorage.getItem('mdbook-theme');
let sidebar = localStorage.getItem('mdbook-sidebar');
if (theme.startsWith('"') && theme.endsWith('"')) {
localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
}
if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
}
} catch (e) { }
</script>
<!-- Set the theme before any content is loaded, prevents flash -->
<script>
const default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? default_dark_theme : default_light_theme;
let theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
const html = document.documentElement;
html.classList.remove('light')
html.classList.add(theme);
html.classList.add("js");
</script>
<input type="checkbox" id="sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("sidebar-toggle-anchor");
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
} else {
sidebar = 'hidden';
}
sidebar_toggle.checked = sidebar === 'visible';
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<!-- populated by js -->
<mdbook-sidebar-scrollbox class="sidebar-scrollbox"></mdbook-sidebar-scrollbox>
<noscript>
<iframe class="sidebar-iframe-outer" src="../../toc.html"></iframe>
</noscript>
<div id="sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="page-wrapper" class="page-wrapper">
<div class="page">
<div id="menu-bar-hover-placeholder"></div>
<div id="menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="sidebar-toggle" class="icon-button" for="sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</label>
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
<i class="fa fa-paint-brush"></i>
</button>
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="ayu">Ayu</button></li>
</ul>
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
<i class="fa fa-search"></i>
</button>
</div>
<h1 class="menu-title">Rust语言圣经(Rust Course)</h1>
<div class="right-buttons">
<a href="../../print.html" title="Print this book" aria-label="Print this book">
<i id="print-button" class="fa fa-print"></i>
</a>
<a href="https://github.com/sunface/rust-course" title="Git repository" aria-label="Git repository">
<i id="git-repository-button" class="fa fa-github"></i>
</a>
<a href="https://github.com/sunface/rust-course/edit/main/src/appendix/rust-versions/1.80.md" title="Suggest an edit" aria-label="Suggest an edit">
<i id="git-edit-button" class="fa fa-edit"></i>
</a>
</div>
</div>
<div id="search-wrapper" class="hidden">
<form id="searchbar-outer" class="searchbar-outer">
<input type="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
</form>
<div id="searchresults-outer" class="searchresults-outer hidden">
<div id="searchresults-header" class="searchresults-header"></div>
<ul id="searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h1 id="rust-新版解读--180--懒类型开区间范围模式"><a class="header" href="#rust-新版解读--180--懒类型开区间范围模式">Rust 新版解读 | 1.80 | “懒”类型、开区间范围模式</a></h1>
<blockquote>
<p>Rust 1.80 官方 release doc: <a href="https://blog.rust-lang.org/2024/07/25/Rust-1.80.0.html">Announcing Rust 1.80.0 | Rust Blog</a></p>
</blockquote>
<p>通过 <a href="https://www.rust-lang.org/tools/install">rustup</a> 安装的同学可以使用以下命令升级到 1.80 版本:</p>
<pre><code class="language-shell">$ rustup update stable
</code></pre>
<h2 id="lazycell-和-lazylock"><a class="header" href="#lazycell-和-lazylock"><code>LazyCell</code><code>LazyLock</code></a></h2>
<p>这两个 "lazy" 类型会延迟数据的初始化直到第一次访问。它们类似于 1.70 版本中稳定的 <code>OnceCell</code><code>OnceLock</code> 类型,但是初始化函数包含在 cell 中。这完成了吸纳流行的 <a href="https://crates.io/crates/lazy-static"><code>lazy_static</code></a><a href="https://crates.io/crates/once_cell"><code>once_cell</code></a> crates 中的功能到标准库中。</p>
<p><code>LazyLock</code> 是线程安全的选项,适用于静态值的场景。例如,下面的例子中,无论是 spawn 线程还是主线程,都会看到相同的时间,因为 <code>LAZY_TIME</code> 只会被初始化一次,由哪个访问静态值的端点先访问。与 <code>OnceLock::get_or_init()</code> 不同,使用方都不需要知道如何初始化它。</p>
<pre><pre class="playground"><code class="language-rust edition2021">use std::sync::LazyLock;
use std::time::Instant;
static LAZY_TIME: LazyLock&lt;Instant&gt; = LazyLock::new(Instant::now);
fn main() {
let start = Instant::now();
std::thread::scope(|s| {
s.spawn(|| {
println!("Thread lazy time is {:?}", LAZY_TIME.duration_since(start));
});
println!("Main lazy time is {:?}", LAZY_TIME.duration_since(start));
});
}</code></pre></pre>
<p><code>LazyCell</code> 也是一样的,只是没有线程同步,所以它不实现 <code>Sync</code>,但是它仍然可以在 <code>thread_local!</code> 静态值中使用(每个线程初始化一次)。取决于线程安全的需求如何,这两种类型都可以在其他数据结构中使用,来达到懒初始化的目的。</p>
<h2 id="cfg-名称和值检查"><a class="header" href="#cfg-名称和值检查"><code>cfg</code> 名称和值检查</a></h2>
<p>在 1.79 版本中rustc 稳定了一个 <a href="https://doc.rust-lang.org/rustc/check-cfg.html"><code>--check-cfg</code> 标志</a>,现在 Cargo 1.80 为所有的 <code>cfg</code> 名称和值启用了这些检查(除了 rustc 中<a href="https://doc.rust-lang.org/rustc/check-cfg.html#well-known-names-and-values">已知的名称和值</a>)。这包括来自 Cargo.toml 的特性名称以及来自构建脚本的新 <code>cargo::rustc-check-cfg</code> 输出。</p>
<p>出现期望外的 cfgs 会默认生成 <code>unexpected_cfgs</code> lint用于捕获拼写错误或其他配置错误。例如在一个有可选的 <code>rayon</code> 特性依赖项的项目中,这段代码配置了错误的特性值:</p>
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
println!("Hello, world!");
#[cfg(feature = "crayon")]
rayon::join(
|| println!("Hello, Thing One!"),
|| println!("Hello, Thing Two!"),
);
}</code></pre></pre>
<pre><code class="language-bash">warning: unexpected `cfg` condition value: `crayon`
--&gt; src/main.rs:4:11
|
4 | #[cfg(feature = "crayon")]
| ^^^^^^^^^^--------
| |
| help: there is a expected value with a similar name: `"rayon"`
|
= note: expected values for `feature` are: `rayon`
= help: consider adding `crayon` as a feature in `Cargo.toml`
= note: see &lt;https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html&gt; for more information about checking conditional configuration
= note: `#[warn(unexpected_cfgs)]` on by default
</code></pre>
<p>无论实际是否启用 rayon 特性,都会报告该警告。</p>
<p><code>Cargo.toml</code> 文件中的 <code>[lints]</code> 部分可以用于扩展自定义 <code>cfg</code> 的已知名称和值列表。<code>rustc</code> 自动提供了警告中使用的<a href="https://doc.rust-lang.org/rustc/check-cfg.html#specifying-expected-names-and-values">语法</a></p>
<pre><code class="language-toml">[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(foo, values("bar"))'] }
</code></pre>
<p>你可以在之前的发布 nightly 时的<a href="https://blog.rust-lang.org/2024/05/06/check-cfg.html">博客文章</a>中阅读更多关于这个特性的内容。</p>
<h2 id="开区间的范围模式"><a class="header" href="#开区间的范围模式">开区间的范围模式</a></h2>
<p>Rust 的范围模式现在可以使用右开区间,写作 <code>a..b</code><code>..b</code>,类似于 <code>Range</code><code>RangeTo</code> 表达式类型。例如,以下模式现在可以使用相同的常量作为一个模式的结束和下一个模式的开始:</p>
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>pub fn size_prefix(n: u32) -&gt; &amp;'static str {
const K: u32 = 10u32.pow(3);
const M: u32 = 10u32.pow(6);
const G: u32 = 10u32.pow(9);
match n {
..K =&gt; "",
K..M =&gt; "k",
M..G =&gt; "M",
G.. =&gt; "G",
}
}
<span class="boring">}</span></code></pre></pre>
<p>之前,范围模式中只允许包含的(<code>a..=b</code><code>..=b</code>)或开放的(<code>a..</code>)范围,所以像这样的代码需要为边界使用一个不同的常量(如 <code>K - 1</code>)。</p>
<p>该特性作为一个不稳定的特性已经实现了很长时间,阻碍其稳定的考虑主要是它可能会增加模式匹配中的混乱程度,增加出现差一错误的机会。为此,穷尽性检查已经得到了增强,以更好地检测模式匹配中的空缺,新的 lint <code>non_contiguous_range_endpoints</code><code>overlapping_range_endpoints</code> 将有助于检测是否正确使用了开区间和闭区间。</p>
<h2 id="others"><a class="header" href="#others">Others</a></h2>
<p>其它更新细节,和稳定的 API 列表,参考<a href="https://blog.rust-lang.org/2024/07/25/Rust-1.80.0.html#stabilized-apis">原Blog</a></p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="../../appendix/rust-versions/1.79.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../../appendix/rust-versions/1.81.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="../../appendix/rust-versions/1.79.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<i class="fa fa-angle-left"></i>
</a>
<a rel="next prefetch" href="../../appendix/rust-versions/1.81.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<i class="fa fa-angle-right"></i>
</a>
</nav>
</div>
<script>
window.playground_copyable = true;
</script>
<script src="../../ace.js"></script>
<script src="../../editor.js"></script>
<script src="../../mode-rust.js"></script>
<script src="../../theme-dawn.js"></script>
<script src="../../theme-tomorrow_night.js"></script>
<script src="../../elasticlunr.min.js"></script>
<script src="../../mark.min.js"></script>
<script src="../../searcher.js"></script>
<script src="../../clipboard.min.js"></script>
<script src="../../highlight.js"></script>
<script src="../../book.js"></script>
<!-- Custom JS scripts -->
<script src="../../assets/custom2.js"></script>
<script src="../../assets/bigPicture.js"></script>
</div>
</body>
</html>