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.

376 lines
25 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.85 - 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.85.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-新版解读--185--rust-2024-稳定版async-闭包"><a class="header" href="#rust-新版解读--185--rust-2024-稳定版async-闭包">Rust 新版解读 | 1.85 | Rust 2024 稳定版、<code>async</code> 闭包</a></h1>
<blockquote>
<p>Rust 1.85 官方 release doc: <a href="https://blog.rust-lang.org/2025/02/20/Rust-1.85.0.html">Announcing Rust 1.85.0 | Rust Blog</a></p>
</blockquote>
<p>通过 <a href="https://www.rust-lang.org/tools/install">rustup</a> 安装的同学可以使用以下命令升级到 1.85 版本:</p>
<pre><code class="language-shell">$ rustup update stable
</code></pre>
<h2 id="rust-2024"><a class="header" href="#rust-2024">Rust 2024</a></h2>
<p>我们很高兴地宣布Rust 2024 版现已稳定!
大的新版本也是一种用于选择可能带来向后兼容性风险的更改的机制。有关如何实现此目标的详细信息以及迁移的详细说明,请参阅<a href="https://doc.rust-lang.org/edition-guide/editions/index.html">版本指南</a></p>
<p><a href="https://doc.rust-lang.org/edition-guide/rust-2024/index.html">版本指南</a>里包含了每个更改的详细信息,这里有一份简要总结:</p>
<ul>
<li>语言
<ul>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/rpit-lifetime-capture.html">RPIT 生命周期捕获规则</a> — 当 <code>use&lt;..&gt;</code> 不存在时,更改 <code>impl Trait</code> 类型对参数的默认捕获。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/temporary-if-let-scope.html"><code>if let</code> 临时作用域</a> — 更改 <code>if let</code> 表达式的临时作用域。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html">尾表达式临时作用域</a> — 更改块中尾表达式的临时作用域。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/match-ergonomics.html">预留模式匹配的人性化改进</a> — 禁止某些模式组合以避免混淆并为未来的改进留出空间。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-extern.html">不安全的 <code>extern</code></a><code>extern</code> 块现在需要 <code>unsafe</code> 关键字。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html">不安全属性</a><code>export_name</code><code>link_section</code><code>no_mangle</code> 属性现在必须标记为 <code>unsafe</code></li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html"><code>unsafe_op_in_unsafe_fn</code> 警告</a><a href="https://doc.rust-lang.org/rustc/lints/listing/allowed-by-default.html#unsafe-op-in-unsafe-fn"><code>unsafe_op_in_unsafe_fn</code></a> lint 现在默认警告,要求在 <code>unsafe</code> 函数中显式使用 <code>unsafe {}</code> 块。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/static-mut-references.html">禁止引用 <code>static mut</code></a> — 对 <code>static mut</code> 项的引用现在会生成默认拒绝的错误。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html">Never 类型 fallback 更改</a> — 更改了 never 类型 <code>!</code> 的强制转换方式,并将 <a href="https://doc.rust-lang.org/rustc/lints/listing/warn-by-default.html#never-type-fallback-flowing-into-unsafe"><code>never_type_fallback_flowing_into_unsafe</code></a> lint 级别更改为“拒绝”。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/macro-fragment-specifiers.html">宏片段说明符</a><code>macro_rules!</code> 宏中的 <code>expr</code> 宏片段说明符现在也匹配 <code>const</code><code>_</code> 表达式。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/missing-macro-fragment-specifiers.html">缺失的宏片段说明符</a><a href="https://doc.rust-lang.org/rustc/lints/listing/deny-by-default.html#missing-fragment-specifier"><code>missing_fragment_specifier</code></a> lint 现在是一个错误,拒绝没有片段说明符类型的宏元变量。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/gen-keyword.html"><code>gen</code> 关键字</a> — 保留 <code>gen</code> 关键字,以便将来添加生成器块。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html">保留语法</a> — 保留 <code>#"foo"#</code> 风格的字符串和 <code>##</code> 标记,以便将来更改如何解析受保护的字符串字面量。</li>
</ul>
</li>
<li>标准库
<ul>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/prelude.html">prelude 的更改</a> — 将 <code>Future</code><code>IntoFuture</code> 添加到 prelude 中。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/intoiterator-box-slice.html"><code>Box&lt;[T]&gt;</code> 添加 <code>IntoIterator</code></a> — 更改了迭代器与 <code>Box&lt;[T]&gt;</code> 的工作方式。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/newly-unsafe-functions.html">新不安全的函数</a><code>std::env::set_var</code><code>std::env::remove_var</code><code>std::os::unix::process::CommandExt::before_exec</code> 现在是不安全的函数。</li>
</ul>
</li>
<li>Cargo
<ul>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/cargo-resolver.html">Cargo: Rust 版本感知解析器</a> — 更改默认依赖解析器行为以考虑 <code>rust-version</code> 字段。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/cargo-table-key-names.html">Cargo: 表和键名一致性</a> — 删除了一些过时的 <code>Cargo.toml</code> 键。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/cargo-inherited-default-features.html">Cargo: 报错错误使用默认特性开关的继承情况</a> — 更改了 <code>default-features = false</code> 与继承的工作区依赖项的工作方式。</li>
</ul>
</li>
<li>Rustdoc
<ul>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/rustdoc-doctests.html">Rustdoc 组合测试</a> — 文档测试现在组合成一个可执行文件,显著提高了性能。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/rustdoc-nested-includes.html">Rustdoc 嵌套 <code>include!</code> 更改</a> — 更改了嵌套 <code>include!</code> 文件的相对路径行为。</li>
</ul>
</li>
<li>Rustfmt
<ul>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/rustfmt-style-edition.html">Rustfmt: 样式版本</a> — 引入了“样式版本”的概念,允许你分开控制格式化版本与 Rust 版本。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/rustfmt-formatting-fixes.html">Rustfmt: 格式化修复</a> — 大量修复了各种情况的格式化问题。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/rustfmt-raw-identifier-sorting.html">Rustfmt: 原始标识符排序</a> — 更改了诸如 <code>r#async</code> 带有 <code>r#</code> 标识符的排序方式。</li>
<li><a href="https://doc.rust-lang.org/edition-guide/rust-2024/rustfmt-version-sorting.html">Rustfmt: 带数字的排序</a> — 更改了包含整数的标识符的排序方式。</li>
</ul>
</li>
</ul>
<h3 id="迁移到-2024"><a class="header" href="#迁移到-2024">迁移到 2024</a></h3>
<p>指南包含了所有新功能的迁移说明,以及<a href="https://doc.rust-lang.org/edition-guide/editions/transitioning-an-existing-project-to-a-new-edition.html">将现有项目迁移到新版本</a>的一般说明。
在许多情况下,<code>cargo fix</code> 可以自动完成必要的更改。你甚至可能会发现2024 版不需要对你的代码进行任何更改!</p>
<p>请注意,通过 <code>cargo fix</code> 进行的自动修复非常保守,以避免更改代码的语义。在许多情况下,你可能希望保持代码不变并使用 Rust 2024 的新语义;例如,继续使用 <code>expr</code> 宏匹配器,并忽略条件表达式的转换,因为你希望使用新的 2024 版 drop 顺序语义。<code>cargo fix</code> 的结果不应被视为建议,而只是保持行为的保守转换。</p>
<h2 id="async-闭包"><a class="header" href="#async-闭包"><code>async</code> 闭包</a></h2>
<p>Rust 现在支持异步闭包,如 <code>async || {}</code>,它在调用时返回 future。这类似于 <code>async fn</code>,它也可以从本地环境中捕获值,就像普通闭包和函数之间的区别一样。标准库 prelude 中还提供了 3 个类似的 trait<code>AsyncFn</code><code>AsyncFnMut</code><code>AsyncFnOnce</code></p>
<p>在某些情况下,你可以通过普通闭包和异步块来近似实现这一点,例如 <code>|| async {}</code>。然而,这种内部块返回的 future 无法从闭包捕获中借用,但 <code>async</code> 闭包可以做到这一点:</p>
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let mut vec: Vec&lt;String&gt; = vec![];
let closure = async || {
vec.push(ready(String::from("")).await);
};
<span class="boring">}</span></code></pre></pre>
<p>此外,使用 <code>Fn</code> trait 返回 <code>Future</code> 时,无法正确表达函数签名,但你可以使用 <code>AsyncFn</code> trait 来编写:</p>
<pre><pre class="playground"><code class="language-rust edition2021">use core::future::Future;
async fn f&lt;Fut&gt;(_: impl for&lt;'a&gt; Fn(&amp;'a u8) -&gt; Fut)
where
Fut: Future&lt;Output = ()&gt;,
{ todo!() }
async fn f2(_: impl for&lt;'a&gt; AsyncFn(&amp;'a u8))
{ todo!() }
async fn main() {
async fn g(_: &amp;u8) { todo!() }
f(g).await;
//~^ ERROR 类型不匹配
//~| ERROR 一个类型比另一个更通用
f2(g).await; // 没问题!
}</code></pre></pre>
<p>因此,<code>async</code> 闭包为这两个问题提供了一流的解决方案!有关更多详细信息,请参阅 <a href="https://rust-lang.github.io/rfcs/3668-async-closures.html">RFC 3668</a><a href="https://github.com/rust-lang/rust/pull/132706">稳定报告</a></p>
<h2 id="从诊断中隐藏-trait-实现"><a class="header" href="#从诊断中隐藏-trait-实现">从诊断中隐藏 trait 实现</a></h2>
<p>新的 <code>#[diagnostic::do_not_recommend]</code> 属性是给编译器的一个提示,不要将注释的 trait 实现显示为诊断消息的一部分。对于库作者来说,这是一种防止编译器提出可能无益或误导的建议的方式。例如:</p>
<pre><pre class="playground"><code class="language-rust edition2021">pub trait Foo {}
pub trait Bar {}
impl&lt;T: Foo&gt; Bar for T {}
struct MyType;
fn main() {
let _object: &amp;dyn Bar = &amp;MyType;
}</code></pre></pre>
<pre><code class="language-text">error[E0277]: 未满足 trait 绑定 `MyType: Bar`
--&gt; src/main.rs:9:29
|
9 | let _object: &amp;dyn Bar = &amp;MyType;
| ^^^^ trait `Foo` 未为 `MyType` 实现
|
note: 需要 `MyType` 实现 `Bar`
--&gt; src/main.rs:4:14
|
4 | impl&lt;T: Foo&gt; Bar for T {}
| --- ^^^ ^
| |
| 在此处引入的未满足的 trait 绑定
= note: 需要将 `&amp;MyType` 转换为 `&amp;dyn Bar`
</code></pre>
<p>对于某些 API实现 <code>Foo</code> 并通过该泛型实现间接获得 <code>Bar</code> 可能是有意义的。对于其他 API可能期望大多数用户直接实现 <code>Bar</code>,因此 <code>Foo</code> 建议是一个误导。在这种情况下,添加诊断提示将更改错误消息如下:</p>
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>#[diagnostic::do_not_recommend]
impl&lt;T: Foo&gt; Bar for T {}
<span class="boring">}</span></code></pre></pre>
<pre><code class="language-text">error[E0277]: 未满足 trait 绑定 `MyType: Bar`
--&gt; src/main.rs:10:29
|
10 | let _object: &amp;dyn Bar = &amp;MyType;
| ^^^^ trait `Bar` 未为 `MyType` 实现
|
= note: 需要将 `&amp;MyType` 转换为 `&amp;dyn Bar`
</code></pre>
<p>有关原始动机,请参阅 <a href="https://rust-lang.github.io/rfcs/2397-do-not-recommend.html">RFC 2397</a>,以及当前的<a href="https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-diagnosticdo_not_recommend-attribute">参考</a>以获取更多详细信息。</p>
<h2 id="元组的-fromiterator-和-extend"><a class="header" href="#元组的-fromiterator-和-extend">元组的 <code>FromIterator</code><code>Extend</code></a></h2>
<p>早期版本的 Rust 为 <code>(T, U)</code> 元组对的迭代器实现了便利的 trait使其行为类似于 <code>Iterator::unzip</code>,其中 <code>Extend</code> 在 1.56 版中实现,<code>FromIterator</code> 在 1.79 版中实现。这些现在已<em>扩展</em>到更多的元组长度,从单例 <code>(T,)</code> 到 12 个元素长的 <code>(T1, T2, .., T11, T12)</code>。例如,你现在可以使用 <code>collect()</code> 一次性分发到多个集合中:</p>
<pre><pre class="playground"><code class="language-rust edition2021">use std::collections::{LinkedList, VecDeque};
fn main() {
let (squares, cubes, tesseracts): (Vec&lt;_&gt;, VecDeque&lt;_&gt;, LinkedList&lt;_&gt;) =
(0i32..10).map(|i| (i * i, i.pow(3), i.pow(4))).collect();
println!("{squares:?}");
println!("{cubes:?}");
println!("{tesseracts:?}");
}</code></pre></pre>
<pre><code class="language-text">[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
[0, 1, 16, 81, 256, 625, 1296, 2401, 4096, 6561]
</code></pre>
<h2 id="stdenvhome_dir-的更新"><a class="header" href="#stdenvhome_dir-的更新"><code>std::env::home_dir()</code> 的更新</a></h2>
<p><code>std::env::home_dir()</code> 已被弃用多年,因为如果设置了 <code>HOME</code> 环境变量(这不是 Windows 上的标准配置),它可能会在某些 Windows 配置中给出令人惊讶的结果。我们之前避免更改其行为,因为担心与依赖此非标准配置的代码的兼容性。鉴于该函数已被弃用很长时间,我们现在将其行为更新为错误修复,后续版本将取消对该函数的弃用。</p>
<h2 id="others"><a class="header" href="#others">Others</a></h2>
<p>其它更新细节,和稳定的 API 列表,参考<a href="https://blog.rust-lang.org/2025/02/20/Rust-1.85.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.84.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.86.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.84.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.86.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>