mirror of
https://github.com/sunface/rust-by-practice.git
synced 2025-06-23 12:39:42 +00:00
deploy
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
book
|
1
.nojekyll
Normal file
1
.nojekyll
Normal file
@ -0,0 +1 @@
|
|||||||
|
This file makes sure that Github Pages doesn't process mdBook's output.
|
211
404.html
Normal file
211
404.html
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Page not found - Rust By Practice</title>
|
||||||
|
<base href="/">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" title="Git repository" aria-label="Git repository">
|
||||||
|
<i id="git-repository-button" class="fa fa-github"></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="document-not-found-404"><a class="header" href="#document-not-found-404">Document not found (404)</a></h1>
|
||||||
|
<p>This URL is invalid, sorry. Please use the navigation bar or search to continue.</p>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
|
||||||
|
|
||||||
|
<div style="clear: both"></div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||||
|
|
||||||
|
</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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
4
FontAwesome/css/font-awesome.css
vendored
Normal file
4
FontAwesome/css/font-awesome.css
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
FontAwesome/fonts/FontAwesome.ttf
Normal file
BIN
FontAwesome/fonts/FontAwesome.ttf
Normal file
Binary file not shown.
BIN
FontAwesome/fonts/fontawesome-webfont.eot
Normal file
BIN
FontAwesome/fonts/fontawesome-webfont.eot
Normal file
Binary file not shown.
2671
FontAwesome/fonts/fontawesome-webfont.svg
Normal file
2671
FontAwesome/fonts/fontawesome-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 434 KiB |
BIN
FontAwesome/fonts/fontawesome-webfont.ttf
Normal file
BIN
FontAwesome/fonts/fontawesome-webfont.ttf
Normal file
Binary file not shown.
BIN
FontAwesome/fonts/fontawesome-webfont.woff
Normal file
BIN
FontAwesome/fonts/fontawesome-webfont.woff
Normal file
Binary file not shown.
BIN
FontAwesome/fonts/fontawesome-webfont.woff2
Normal file
BIN
FontAwesome/fonts/fontawesome-webfont.woff2
Normal file
Binary file not shown.
156
assets/custom3.js
Normal file
156
assets/custom3.js
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
var initAll = function () {
|
||||||
|
var path = window.location.pathname;
|
||||||
|
if (path.endsWith("/print.html")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var images = document.querySelectorAll("main img")
|
||||||
|
Array.prototype.forEach.call(images, function (img) {
|
||||||
|
img.addEventListener("click", function () {
|
||||||
|
BigPicture({
|
||||||
|
el: img,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Un-active everything when you click it
|
||||||
|
Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function (el) {
|
||||||
|
el.addEventHandler("click", function () {
|
||||||
|
Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function (el) {
|
||||||
|
el.classList.remove("active");
|
||||||
|
});
|
||||||
|
el.classList.add("active");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var updateFunction = function () {
|
||||||
|
var id = null;
|
||||||
|
var elements = document.getElementsByClassName("header");
|
||||||
|
Array.prototype.forEach.call(elements, function (el) {
|
||||||
|
if (window.pageYOffset >= el.offsetTop) {
|
||||||
|
id = el;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function (el) {
|
||||||
|
el.classList.remove("active");
|
||||||
|
});
|
||||||
|
|
||||||
|
Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function (el) {
|
||||||
|
if (id == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (id.href.localeCompare(el.href) == 0) {
|
||||||
|
el.classList.add("active");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var pagetoc = document.getElementsByClassName("pagetoc")[0];
|
||||||
|
var elements = document.getElementsByClassName("header");
|
||||||
|
Array.prototype.forEach.call(elements, function (el) {
|
||||||
|
var link = document.createElement("a");
|
||||||
|
|
||||||
|
// Indent shows hierarchy
|
||||||
|
var indent = "";
|
||||||
|
switch (el.parentElement.tagName) {
|
||||||
|
case "H1":
|
||||||
|
return;
|
||||||
|
case "H3":
|
||||||
|
indent = "20px";
|
||||||
|
break;
|
||||||
|
case "H4":
|
||||||
|
indent = "40px";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
link.appendChild(document.createTextNode(el.text));
|
||||||
|
link.style.paddingLeft = indent;
|
||||||
|
link.href = el.href;
|
||||||
|
pagetoc.appendChild(link);
|
||||||
|
});
|
||||||
|
updateFunction.call();
|
||||||
|
|
||||||
|
// Handle active elements on scroll
|
||||||
|
window.addEventListener("scroll", updateFunction);
|
||||||
|
|
||||||
|
document.getElementById("theme-list").addEventListener("click", function (e) {
|
||||||
|
var iframe = document.querySelector('.giscus-frame');
|
||||||
|
if (!iframe) return;
|
||||||
|
var theme;
|
||||||
|
if (e.target.className === "theme") {
|
||||||
|
theme = e.target.id;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 若当前 mdbook 主题不是 Light 或 Rust ,则将 giscuz 主题设置为 transparent_dark
|
||||||
|
var giscusTheme = "light"
|
||||||
|
if (theme != "light" && theme != "rust") {
|
||||||
|
giscusTheme = "transparent_dark";
|
||||||
|
}
|
||||||
|
|
||||||
|
var msg = {
|
||||||
|
setConfig: {
|
||||||
|
theme: giscusTheme
|
||||||
|
}
|
||||||
|
};
|
||||||
|
iframe.contentWindow.postMessage({ giscus: msg }, 'https://giscus.app');
|
||||||
|
});
|
||||||
|
|
||||||
|
pagePath = pagePath.replace("index.md", "");
|
||||||
|
pagePath = pagePath.replace(".md", "");
|
||||||
|
if (pagePath.length > 0) {
|
||||||
|
if (pagePath.charAt(pagePath.length-1) == "/"){
|
||||||
|
pagePath = pagePath.substring(0, pagePath.length-1)
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
pagePath = "index"
|
||||||
|
}
|
||||||
|
|
||||||
|
// add visitors count
|
||||||
|
var ele = document.createElement("div");
|
||||||
|
ele.setAttribute("align","center");
|
||||||
|
var count = document.createElement("img")
|
||||||
|
// count.setAttribute("src", "https://visitor-badge.glitch.me/badge?page_id=practice/en/" + path);
|
||||||
|
count.setAttribute("src", "https://api.visitorbadge.io/api/visitors?labelColor=%23595959&countColor=%230d81c3&style=flat-square&path=practice/en/" + path);
|
||||||
|
ele.appendChild(count);
|
||||||
|
var divider =document.createElement("hr")
|
||||||
|
|
||||||
|
document.getElementById("giscus-container").appendChild(ele);
|
||||||
|
document.getElementById("giscus-container").appendChild(divider);
|
||||||
|
|
||||||
|
// 选取浏览器默认使用的语言
|
||||||
|
const lang = navigator.language || navigator.userLanguage
|
||||||
|
|
||||||
|
// 若当前 mdbook 主题为 Light 或 Rust ,则将 giscuz 主题设置为 light
|
||||||
|
var theme = "transparent_dark";
|
||||||
|
const themeClass = document.getElementsByTagName("html")[0].className;
|
||||||
|
if (themeClass.indexOf("light") != -1 || themeClass.indexOf("rust") != -1) {
|
||||||
|
theme = "light"
|
||||||
|
}
|
||||||
|
|
||||||
|
var script = document.createElement("script")
|
||||||
|
script.type = "text/javascript";
|
||||||
|
script.src = "https://giscus.app/client.js";
|
||||||
|
script.async = true;
|
||||||
|
script.crossOrigin = "anonymous";
|
||||||
|
script.setAttribute("data-repo", "sunface/rust-by-practice");
|
||||||
|
script.setAttribute("data-repo-id", "MDEwOlJlcG9zaXRvcnkxMjk5OTAzOTY=");
|
||||||
|
script.setAttribute("data-category", "Book Comments");
|
||||||
|
script.setAttribute("data-category-id", "DIC_kwDOB79-_M4COQmx");
|
||||||
|
script.setAttribute("data-mapping", "specific");
|
||||||
|
script.setAttribute("data-term", pagePath);
|
||||||
|
script.setAttribute("data-reactions-enabled", "1");
|
||||||
|
script.setAttribute("data-emit-metadata", "0");
|
||||||
|
script.setAttribute("data-input-position", "top");
|
||||||
|
script.setAttribute("data-theme", theme);
|
||||||
|
script.setAttribute("data-lang", lang == 'en-US' ? 'en' : lang);
|
||||||
|
// 预先加载评论会更好,这样用户读到那边时,评论就加载好了
|
||||||
|
// script.setAttribute("data-loading", "lazy");
|
||||||
|
document.getElementById("giscus-container").appendChild(script);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('load', initAll);
|
35
assets/lang1.js
Normal file
35
assets/lang1.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
(function () {
|
||||||
|
var path = window.location.pathname;
|
||||||
|
var link = "https://practice.course.rs" + path;
|
||||||
|
var word = "English";
|
||||||
|
var lang = "zh-CN";
|
||||||
|
var changeLang = "切换到英语";
|
||||||
|
|
||||||
|
if (window.location.href.indexOf("zh.") == -1) {
|
||||||
|
link = "https://practice-zh.course.rs" + path;
|
||||||
|
word = "简体中文";
|
||||||
|
lang = "en";
|
||||||
|
changeLang = "Switch to Chinese";
|
||||||
|
}
|
||||||
|
|
||||||
|
var lang_node = "";
|
||||||
|
if (link != "") {
|
||||||
|
lang_node =
|
||||||
|
'<a href="' +
|
||||||
|
link +
|
||||||
|
'" title="' +
|
||||||
|
changeLang +
|
||||||
|
'" aria-label="' +
|
||||||
|
changeLang +
|
||||||
|
'"><i id="change-language-button" class="fa fa-language"> ' +
|
||||||
|
word +
|
||||||
|
"</i></a>";
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(lang_node);
|
||||||
|
var insertNode = document.getElementsByClassName("right-buttons");
|
||||||
|
if (insertNode.length > 0) {
|
||||||
|
var html = insertNode[0].innerHTML;
|
||||||
|
insertNode[0].innerHTML = html + lang_node;
|
||||||
|
}
|
||||||
|
})();
|
224
async/async-await.html
Normal file
224
async/async-await.html
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>async and await! - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/async/async-await.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="async-and-await"><a class="header" href="#async-and-await">async and await!</a></h1>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../async/intro.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="../async/future.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="../async/intro.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="../async/future.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
224
async/future.html
Normal file
224
async/future.html
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Future - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/async/future.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="future"><a class="header" href="#future">Future</a></h1>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../async/async-await.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="../async/pin-unpin.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="../async/async-await.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="../async/pin-unpin.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
224
async/intro.html
Normal file
224
async/intro.html
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Async/Await TODO - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/async/intro.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="asyncawait"><a class="header" href="#asyncawait">Async/Await</a></h1>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../tests/assertions.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="../async/async-await.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="../tests/assertions.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="../async/async-await.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
224
async/pin-unpin.html
Normal file
224
async/pin-unpin.html
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Pin and Unpin - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/async/pin-unpin.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="pin-and-unpin"><a class="header" href="#pin-and-unpin">Pin and Unpin</a></h1>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../async/future.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="../async/stream.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="../async/future.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="../async/stream.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
224
async/stream.html
Normal file
224
async/stream.html
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Stream - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/async/stream.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="stream"><a class="header" href="#stream">Stream</a></h1>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../async/pin-unpin.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="../std/intro.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="../async/pin-unpin.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="../std/intro.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
78
ayu-highlight.css
Normal file
78
ayu-highlight.css
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
Based off of the Ayu theme
|
||||||
|
Original by Dempfi (https://github.com/dempfi/ayu)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
background: #191f26;
|
||||||
|
color: #e6e1cf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote {
|
||||||
|
color: #5c6773;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-link,
|
||||||
|
.hljs-selector-id,
|
||||||
|
.hljs-selector-class {
|
||||||
|
color: #ff7733;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-meta,
|
||||||
|
.hljs-builtin-name,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-params {
|
||||||
|
color: #ffee99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-bullet {
|
||||||
|
color: #b8cc52;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-section {
|
||||||
|
color: #ffb454;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-symbol {
|
||||||
|
color: #ff7733;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-name {
|
||||||
|
color: #36a3d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-tag {
|
||||||
|
color: #00568d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-emphasis {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition {
|
||||||
|
color: #91b362;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion {
|
||||||
|
color: #d96c75;
|
||||||
|
}
|
317
basic-types/char-bool-unit.html
Normal file
317
basic-types/char-bool-unit.html
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Char, Bool and Unit - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/basic-types/char-bool-unit.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="char-bool-and-unit"><a class="header" href="#char-bool-and-unit">Char, Bool and Unit</a></h1>
|
||||||
|
<h3 id="char"><a class="header" href="#char">Char</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Make it work
|
||||||
|
use std::mem::size_of_val;
|
||||||
|
fn main() {
|
||||||
|
let c1 = 'a';
|
||||||
|
assert_eq!(size_of_val(&c1),1);
|
||||||
|
|
||||||
|
let c2 = '中';
|
||||||
|
assert_eq!(size_of_val(&c2),3);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Make it work
|
||||||
|
fn main() {
|
||||||
|
let c1 = "中";
|
||||||
|
print_char(c1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_char(c : char) {
|
||||||
|
println!("{}", c);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="bool"><a class="header" href="#bool">Bool</a></h3>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Make println! work
|
||||||
|
fn main() {
|
||||||
|
let _f: bool = false;
|
||||||
|
|
||||||
|
let t = true;
|
||||||
|
if !t {
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Make it work
|
||||||
|
fn main() {
|
||||||
|
let f = true;
|
||||||
|
let t = true && false;
|
||||||
|
assert_eq!(t, f);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="unit-type"><a class="header" href="#unit-type">Unit type</a></h3>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Make it work, don't modify `implicitly_ret_unit` !
|
||||||
|
fn main() {
|
||||||
|
let _v: () = ();
|
||||||
|
|
||||||
|
let v = (2, 3);
|
||||||
|
assert_eq!(v, implicitly_ret_unit());
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn implicitly_ret_unit() {
|
||||||
|
println!("I will return a ()");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't use this one
|
||||||
|
fn explicitly_ret_unit() -> () {
|
||||||
|
println!("I will return a ()");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟 What's the size of the unit type?</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Modify `4` in assert to make it work
|
||||||
|
use std::mem::size_of_val;
|
||||||
|
fn main() {
|
||||||
|
let unit: () = ();
|
||||||
|
assert!(size_of_val(&unit) == 4);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../basic-types/numbers.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="../basic-types/statements-expressions.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="../basic-types/numbers.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="../basic-types/statements-expressions.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
317
basic-types/functions.html
Normal file
317
basic-types/functions.html
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Functions - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/basic-types/functions.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="functions"><a class="header" href="#functions">Functions</a></h1>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// Don't modify the following two lines!
|
||||||
|
let (x, y) = (1, 2);
|
||||||
|
let s = sum(x, y);
|
||||||
|
|
||||||
|
assert_eq!(s, 3);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sum(x, y: i32) {
|
||||||
|
x + y;
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
print();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace i32 with another type
|
||||||
|
fn print() -> i32 {
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// Solve it in two ways
|
||||||
|
// DON'T let `println!` work
|
||||||
|
fn main() {
|
||||||
|
never_return();
|
||||||
|
|
||||||
|
println!("Failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn never_return() -> ! {
|
||||||
|
// Implement this function, don't modify the fn signatures
|
||||||
|
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="diverging-functions"><a class="header" href="#diverging-functions">Diverging functions</a></h3>
|
||||||
|
<p>Diverging functions never return to the caller, so they may be used in places where a value of any type is expected.</p>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_option(tp: u8) -> Option<i32> {
|
||||||
|
match tp {
|
||||||
|
1 => {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rather than returning a None, we use a diverging function instead
|
||||||
|
never_return_fn()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMPLEMENT this function in THREE ways
|
||||||
|
fn never_return_fn() -> ! {
|
||||||
|
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// FILL in the blank
|
||||||
|
let b = __;
|
||||||
|
|
||||||
|
let _v = match b {
|
||||||
|
true => 1,
|
||||||
|
// Diverging functions can also be used in match expression to replace a value of any value
|
||||||
|
false => {
|
||||||
|
println!("Success!");
|
||||||
|
panic!("we have no value for `false`, but we can panic");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Exercise Failed if printing out this line!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/basic-types/functions.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../basic-types/statements-expressions.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="../ownership/intro.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="../basic-types/statements-expressions.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="../ownership/intro.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
229
basic-types/intro.html
Normal file
229
basic-types/intro.html
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Basic Types - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/basic-types/intro.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="basic-types"><a class="header" href="#basic-types">Basic Types</a></h1>
|
||||||
|
<p>Learning resources:</p>
|
||||||
|
<ul>
|
||||||
|
<li>English: <a href="https://doc.rust-lang.org/book/ch03-02-data-types.html">Rust Book 3.2 and 3.3</a></li>
|
||||||
|
<li>简体中文: <a href="https://course.rs/basic/base-type/index.html">Rust语言圣经 - 基本类型</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../variables.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="../basic-types/numbers.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="../variables.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="../basic-types/numbers.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
393
basic-types/numbers.html
Normal file
393
basic-types/numbers.html
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Numbers - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/basic-types/numbers.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="numbers"><a class="header" href="#numbers">Numbers</a></h1>
|
||||||
|
<h3 id="integer"><a class="header" href="#integer">Integer</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<blockquote>
|
||||||
|
<p>Tips: If we don't explicitly assign a type to a variable, then the compiler will infer one for us.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Remove something to make it work
|
||||||
|
fn main() {
|
||||||
|
let x: i32 = 5;
|
||||||
|
let mut y: u32 = 5;
|
||||||
|
|
||||||
|
y = x;
|
||||||
|
|
||||||
|
let z = 10; // Type of z ?
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blank
|
||||||
|
fn main() {
|
||||||
|
let v: u16 = 38_u8 as __;
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<blockquote>
|
||||||
|
<p>Tips: If we don't explicitly assign a type to a variable, then the compiler will infer one for us.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Modify `assert_eq!` to make it work
|
||||||
|
fn main() {
|
||||||
|
let x = 5;
|
||||||
|
assert_eq!("u32".to_string(), type_of(&x));
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the type of given variable, return a string representation of the type , e.g "i8", "u8", "i32", "u32"
|
||||||
|
fn type_of<T>(_: &T) -> String {
|
||||||
|
format!("{}", std::any::type_name::<T>())
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blanks to make it work
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(i8::MAX, __);
|
||||||
|
assert_eq!(u8::MAX, __);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix errors and panics to make it work
|
||||||
|
fn main() {
|
||||||
|
let v1 = 251_u8 + 8;
|
||||||
|
let v2 = i8::checked_add(251, 8).unwrap();
|
||||||
|
println!("{},{}",v1,v2);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Modify `assert!` to make it work
|
||||||
|
fn main() {
|
||||||
|
let v = 1_024 + 0xff + 0o77 + 0b1111_1111;
|
||||||
|
assert!(v == 1579);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="floating-point"><a class="header" href="#floating-point">Floating-Point</a></h3>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blank to make it work
|
||||||
|
fn main() {
|
||||||
|
let x = 1_000.000_1; // ?
|
||||||
|
let y: f32 = 0.12; // f32
|
||||||
|
let z = 0.01_f64; // f64
|
||||||
|
|
||||||
|
assert_eq!(type_of(&x), "__".to_string());
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn type_of<T>(_: &T) -> String {
|
||||||
|
format!("{}", std::any::type_name::<T>())
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟 Make it work in two distinct ways</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
assert!(0.1+0.2==0.3);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="range"><a class="header" href="#range">Range</a></h3>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟🌟 Two goals: 1. Modify <code>assert!</code> to make it work 2. Make <code>println!</code> output list of numbers between 97 and 122</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
let mut sum = 0;
|
||||||
|
for i in -3..2 {
|
||||||
|
sum += i
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(sum == -3);
|
||||||
|
|
||||||
|
for c in 'a'..='z' {
|
||||||
|
println!("{}",c);
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="10">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blanks
|
||||||
|
use std::ops::{Range, RangeInclusive};
|
||||||
|
fn main() {
|
||||||
|
assert_eq!((1..__), Range{ start: 1, end: 5 });
|
||||||
|
assert_eq!((1..__), RangeInclusive::new(1, 5));
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="computations"><a class="header" href="#computations">Computations</a></h3>
|
||||||
|
<ol start="11">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blanks and fix the errors
|
||||||
|
fn main() {
|
||||||
|
// Integer addition
|
||||||
|
assert!(1u32 + 2 == __);
|
||||||
|
|
||||||
|
// Integer subtraction
|
||||||
|
assert!(1i32 - 2 == __);
|
||||||
|
assert!(1u8 - 2 == -1);
|
||||||
|
|
||||||
|
assert!(3 * 50 == __);
|
||||||
|
|
||||||
|
assert!(9.6 / 3.2 == 3.0); // error ! make it work
|
||||||
|
|
||||||
|
assert!(24 % 5 == __);
|
||||||
|
// Short-circuiting boolean logic
|
||||||
|
assert!(true && false == __);
|
||||||
|
assert!(true || false == __);
|
||||||
|
assert!(!true == __);
|
||||||
|
|
||||||
|
// Bitwise operations
|
||||||
|
println!("0011 AND 0101 is {:04b}", 0b0011u32 & 0b0101);
|
||||||
|
println!("0011 OR 0101 is {:04b}", 0b0011u32 | 0b0101);
|
||||||
|
println!("0011 XOR 0101 is {:04b}", 0b0011u32 ^ 0b0101);
|
||||||
|
println!("1 << 5 is {}", 1u32 << 5);
|
||||||
|
println!("0x80 >> 2 is 0x{:x}", 0x80u32 >> 2);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/basic-types/numbers.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../basic-types/intro.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="../basic-types/char-bool-unit.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="../basic-types/intro.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="../basic-types/char-bool-unit.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
288
basic-types/statements-expressions.html
Normal file
288
basic-types/statements-expressions.html
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Statements and Expressions - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/basic-types/statements-expressions.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="statements-and-expressions"><a class="header" href="#statements-and-expressions">Statements and Expressions</a></h1>
|
||||||
|
<h3 id="examples"><a class="header" href="#examples">Examples</a></h3>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
let x = 5u32;
|
||||||
|
|
||||||
|
let y = {
|
||||||
|
let x_squared = x * x;
|
||||||
|
let x_cube = x_squared * x;
|
||||||
|
|
||||||
|
// This expression will be assigned to `y`
|
||||||
|
x_cube + x_squared + x
|
||||||
|
};
|
||||||
|
|
||||||
|
let z = {
|
||||||
|
// The semicolon suppresses this expression and `()` is assigned to `z`
|
||||||
|
2 * x;
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("x is {:?}", x);
|
||||||
|
println!("y is {:?}", y);
|
||||||
|
println!("z is {:?}", z);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="exercises"><a class="header" href="#exercises">Exercises</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// Make it work with two ways
|
||||||
|
fn main() {
|
||||||
|
let v = {
|
||||||
|
let mut x = 1;
|
||||||
|
x += 2
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(v, 3);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let v = (let x = 3);
|
||||||
|
|
||||||
|
assert!(v == 3);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let s = sum(1 , 2);
|
||||||
|
assert_eq!(s, 3);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sum(x: i32, y: i32) -> i32 {
|
||||||
|
x + y
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../basic-types/char-bool-unit.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="../basic-types/functions.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="../basic-types/char-bool-unit.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="../basic-types/functions.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
769
book.js
Normal file
769
book.js
Normal file
@ -0,0 +1,769 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/* global default_theme, default_dark_theme, default_light_theme, hljs, ClipboardJS */
|
||||||
|
|
||||||
|
// Fix back button cache problem
|
||||||
|
window.onunload = function() { };
|
||||||
|
|
||||||
|
// Global variable, shared between modules
|
||||||
|
function playground_text(playground, hidden = true) {
|
||||||
|
const code_block = playground.querySelector('code');
|
||||||
|
|
||||||
|
if (window.ace && code_block.classList.contains('editable')) {
|
||||||
|
const editor = window.ace.edit(code_block);
|
||||||
|
return editor.getValue();
|
||||||
|
} else if (hidden) {
|
||||||
|
return code_block.textContent;
|
||||||
|
} else {
|
||||||
|
return code_block.innerText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(function codeSnippets() {
|
||||||
|
function fetch_with_timeout(url, options, timeout = 6000) {
|
||||||
|
return Promise.race([
|
||||||
|
fetch(url, options),
|
||||||
|
new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const playgrounds = Array.from(document.querySelectorAll('.playground'));
|
||||||
|
if (playgrounds.length > 0) {
|
||||||
|
fetch_with_timeout('https://play.rust-lang.org/meta/crates', {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
mode: 'cors',
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => {
|
||||||
|
// get list of crates available in the rust playground
|
||||||
|
const playground_crates = response.crates.map(item => item['id']);
|
||||||
|
playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle_crate_list_update(playground_block, playground_crates) {
|
||||||
|
// update the play buttons after receiving the response
|
||||||
|
update_play_button(playground_block, playground_crates);
|
||||||
|
|
||||||
|
// and install on change listener to dynamically update ACE editors
|
||||||
|
if (window.ace) {
|
||||||
|
const code_block = playground_block.querySelector('code');
|
||||||
|
if (code_block.classList.contains('editable')) {
|
||||||
|
const editor = window.ace.edit(code_block);
|
||||||
|
editor.addEventListener('change', () => {
|
||||||
|
update_play_button(playground_block, playground_crates);
|
||||||
|
});
|
||||||
|
// add Ctrl-Enter command to execute rust code
|
||||||
|
editor.commands.addCommand({
|
||||||
|
name: 'run',
|
||||||
|
bindKey: {
|
||||||
|
win: 'Ctrl-Enter',
|
||||||
|
mac: 'Ctrl-Enter',
|
||||||
|
},
|
||||||
|
exec: _editor => run_rust_code(playground_block),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// updates the visibility of play button based on `no_run` class and
|
||||||
|
// used crates vs ones available on https://play.rust-lang.org
|
||||||
|
function update_play_button(pre_block, playground_crates) {
|
||||||
|
const play_button = pre_block.querySelector('.play-button');
|
||||||
|
|
||||||
|
// skip if code is `no_run`
|
||||||
|
if (pre_block.querySelector('code').classList.contains('no_run')) {
|
||||||
|
play_button.classList.add('hidden');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get list of `extern crate`'s from snippet
|
||||||
|
const txt = playground_text(pre_block);
|
||||||
|
const re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
|
||||||
|
const snippet_crates = [];
|
||||||
|
let item;
|
||||||
|
// eslint-disable-next-line no-cond-assign
|
||||||
|
while (item = re.exec(txt)) {
|
||||||
|
snippet_crates.push(item[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if all used crates are available on play.rust-lang.org
|
||||||
|
const all_available = snippet_crates.every(function(elem) {
|
||||||
|
return playground_crates.indexOf(elem) > -1;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (all_available) {
|
||||||
|
play_button.classList.remove('hidden');
|
||||||
|
} else {
|
||||||
|
play_button.classList.add('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_rust_code(code_block) {
|
||||||
|
let result_block = code_block.querySelector('.result');
|
||||||
|
if (!result_block) {
|
||||||
|
result_block = document.createElement('code');
|
||||||
|
result_block.className = 'result hljs language-bash';
|
||||||
|
|
||||||
|
code_block.append(result_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
const text = playground_text(code_block);
|
||||||
|
const classes = code_block.querySelector('code').classList;
|
||||||
|
let edition = '2015';
|
||||||
|
classes.forEach(className => {
|
||||||
|
if (className.startsWith('edition')) {
|
||||||
|
edition = className.slice(7);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const params = {
|
||||||
|
version: 'stable',
|
||||||
|
optimize: '0',
|
||||||
|
code: text,
|
||||||
|
edition: edition,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (text.indexOf('#![feature') !== -1) {
|
||||||
|
params.version = 'nightly';
|
||||||
|
}
|
||||||
|
|
||||||
|
result_block.innerText = 'Running...';
|
||||||
|
|
||||||
|
fetch_with_timeout('https://play.rust-lang.org/evaluate.json', {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
method: 'POST',
|
||||||
|
mode: 'cors',
|
||||||
|
body: JSON.stringify(params),
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(response => {
|
||||||
|
if (response.result.trim() === '') {
|
||||||
|
result_block.innerText = 'No output';
|
||||||
|
result_block.classList.add('result-no-output');
|
||||||
|
} else {
|
||||||
|
result_block.innerText = response.result;
|
||||||
|
result_block.classList.remove('result-no-output');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => result_block.innerText = 'Playground Communication: ' + error.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Syntax highlighting Configuration
|
||||||
|
hljs.configure({
|
||||||
|
tabReplace: ' ', // 4 spaces
|
||||||
|
languages: [], // Languages used for auto-detection
|
||||||
|
});
|
||||||
|
|
||||||
|
const code_nodes = Array
|
||||||
|
.from(document.querySelectorAll('code'))
|
||||||
|
// Don't highlight `inline code` blocks in headers.
|
||||||
|
.filter(function(node) {
|
||||||
|
return !node.parentElement.classList.contains('header');
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.ace) {
|
||||||
|
// language-rust class needs to be removed for editable
|
||||||
|
// blocks or highlightjs will capture events
|
||||||
|
code_nodes
|
||||||
|
.filter(function(node) {
|
||||||
|
return node.classList.contains('editable');
|
||||||
|
})
|
||||||
|
.forEach(function(block) {
|
||||||
|
block.classList.remove('language-rust');
|
||||||
|
});
|
||||||
|
|
||||||
|
code_nodes
|
||||||
|
.filter(function(node) {
|
||||||
|
return !node.classList.contains('editable');
|
||||||
|
})
|
||||||
|
.forEach(function(block) {
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
code_nodes.forEach(function(block) {
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding the hljs class gives code blocks the color css
|
||||||
|
// even if highlighting doesn't apply
|
||||||
|
code_nodes.forEach(function(block) {
|
||||||
|
block.classList.add('hljs');
|
||||||
|
});
|
||||||
|
|
||||||
|
Array.from(document.querySelectorAll('code.hljs')).forEach(function(block) {
|
||||||
|
|
||||||
|
const lines = Array.from(block.querySelectorAll('.boring'));
|
||||||
|
// If no lines were hidden, return
|
||||||
|
if (!lines.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
block.classList.add('hide-boring');
|
||||||
|
|
||||||
|
const buttons = document.createElement('div');
|
||||||
|
buttons.className = 'buttons';
|
||||||
|
buttons.innerHTML = '<button class="fa fa-eye" title="Show hidden lines" \
|
||||||
|
aria-label="Show hidden lines"></button>';
|
||||||
|
|
||||||
|
// add expand button
|
||||||
|
const pre_block = block.parentNode;
|
||||||
|
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||||
|
|
||||||
|
pre_block.querySelector('.buttons').addEventListener('click', function(e) {
|
||||||
|
if (e.target.classList.contains('fa-eye')) {
|
||||||
|
e.target.classList.remove('fa-eye');
|
||||||
|
e.target.classList.add('fa-eye-slash');
|
||||||
|
e.target.title = 'Hide lines';
|
||||||
|
e.target.setAttribute('aria-label', e.target.title);
|
||||||
|
|
||||||
|
block.classList.remove('hide-boring');
|
||||||
|
} else if (e.target.classList.contains('fa-eye-slash')) {
|
||||||
|
e.target.classList.remove('fa-eye-slash');
|
||||||
|
e.target.classList.add('fa-eye');
|
||||||
|
e.target.title = 'Show hidden lines';
|
||||||
|
e.target.setAttribute('aria-label', e.target.title);
|
||||||
|
|
||||||
|
block.classList.add('hide-boring');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.playground_copyable) {
|
||||||
|
Array.from(document.querySelectorAll('pre code')).forEach(function(block) {
|
||||||
|
const pre_block = block.parentNode;
|
||||||
|
if (!pre_block.classList.contains('playground')) {
|
||||||
|
let buttons = pre_block.querySelector('.buttons');
|
||||||
|
if (!buttons) {
|
||||||
|
buttons = document.createElement('div');
|
||||||
|
buttons.className = 'buttons';
|
||||||
|
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
const clipButton = document.createElement('button');
|
||||||
|
clipButton.className = 'clip-button';
|
||||||
|
clipButton.title = 'Copy to clipboard';
|
||||||
|
clipButton.setAttribute('aria-label', clipButton.title);
|
||||||
|
clipButton.innerHTML = '<i class="tooltiptext"></i>';
|
||||||
|
|
||||||
|
buttons.insertBefore(clipButton, buttons.firstChild);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process playground code blocks
|
||||||
|
Array.from(document.querySelectorAll('.playground')).forEach(function(pre_block) {
|
||||||
|
// Add play button
|
||||||
|
let buttons = pre_block.querySelector('.buttons');
|
||||||
|
if (!buttons) {
|
||||||
|
buttons = document.createElement('div');
|
||||||
|
buttons.className = 'buttons';
|
||||||
|
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
const runCodeButton = document.createElement('button');
|
||||||
|
runCodeButton.className = 'fa fa-play play-button';
|
||||||
|
runCodeButton.hidden = true;
|
||||||
|
runCodeButton.title = 'Run this code';
|
||||||
|
runCodeButton.setAttribute('aria-label', runCodeButton.title);
|
||||||
|
|
||||||
|
buttons.insertBefore(runCodeButton, buttons.firstChild);
|
||||||
|
runCodeButton.addEventListener('click', () => {
|
||||||
|
run_rust_code(pre_block);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (window.playground_copyable) {
|
||||||
|
const copyCodeClipboardButton = document.createElement('button');
|
||||||
|
copyCodeClipboardButton.className = 'clip-button';
|
||||||
|
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
|
||||||
|
copyCodeClipboardButton.title = 'Copy to clipboard';
|
||||||
|
copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
|
||||||
|
|
||||||
|
buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
|
||||||
|
}
|
||||||
|
|
||||||
|
const code_block = pre_block.querySelector('code');
|
||||||
|
if (window.ace && code_block.classList.contains('editable')) {
|
||||||
|
const undoChangesButton = document.createElement('button');
|
||||||
|
undoChangesButton.className = 'fa fa-history reset-button';
|
||||||
|
undoChangesButton.title = 'Undo changes';
|
||||||
|
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
|
||||||
|
|
||||||
|
buttons.insertBefore(undoChangesButton, buttons.firstChild);
|
||||||
|
|
||||||
|
undoChangesButton.addEventListener('click', function() {
|
||||||
|
const editor = window.ace.edit(code_block);
|
||||||
|
editor.setValue(editor.originalCode);
|
||||||
|
editor.clearSelection();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function themes() {
|
||||||
|
const html = document.querySelector('html');
|
||||||
|
const themeToggleButton = document.getElementById('theme-toggle');
|
||||||
|
const themePopup = document.getElementById('theme-list');
|
||||||
|
const themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
||||||
|
const themeIds = [];
|
||||||
|
themePopup.querySelectorAll('button.theme').forEach(function(el) {
|
||||||
|
themeIds.push(el.id);
|
||||||
|
});
|
||||||
|
const stylesheets = {
|
||||||
|
ayuHighlight: document.querySelector('#ayu-highlight-css'),
|
||||||
|
tomorrowNight: document.querySelector('#tomorrow-night-css'),
|
||||||
|
highlight: document.querySelector('#highlight-css'),
|
||||||
|
};
|
||||||
|
|
||||||
|
function showThemes() {
|
||||||
|
themePopup.style.display = 'block';
|
||||||
|
themeToggleButton.setAttribute('aria-expanded', true);
|
||||||
|
themePopup.querySelector('button#' + get_theme()).focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateThemeSelected() {
|
||||||
|
themePopup.querySelectorAll('.theme-selected').forEach(function(el) {
|
||||||
|
el.classList.remove('theme-selected');
|
||||||
|
});
|
||||||
|
const selected = get_saved_theme() ?? 'default_theme';
|
||||||
|
let element = themePopup.querySelector('button#' + selected);
|
||||||
|
if (element === null) {
|
||||||
|
// Fall back in case there is no "Default" item.
|
||||||
|
element = themePopup.querySelector('button#' + get_theme());
|
||||||
|
}
|
||||||
|
element.classList.add('theme-selected');
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideThemes() {
|
||||||
|
themePopup.style.display = 'none';
|
||||||
|
themeToggleButton.setAttribute('aria-expanded', false);
|
||||||
|
themeToggleButton.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_saved_theme() {
|
||||||
|
let theme = null;
|
||||||
|
try {
|
||||||
|
theme = localStorage.getItem('mdbook-theme');
|
||||||
|
} catch (e) {
|
||||||
|
// ignore error.
|
||||||
|
}
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete_saved_theme() {
|
||||||
|
localStorage.removeItem('mdbook-theme');
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_theme() {
|
||||||
|
const theme = get_saved_theme();
|
||||||
|
if (theme === null || theme === undefined || !themeIds.includes(theme)) {
|
||||||
|
if (typeof default_dark_theme === 'undefined') {
|
||||||
|
// A customized index.hbs might not define this, so fall back to
|
||||||
|
// old behavior of determining the default on page load.
|
||||||
|
return default_theme;
|
||||||
|
}
|
||||||
|
return window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||||
|
? default_dark_theme
|
||||||
|
: default_light_theme;
|
||||||
|
} else {
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let previousTheme = default_theme;
|
||||||
|
function set_theme(theme, store = true) {
|
||||||
|
let ace_theme;
|
||||||
|
|
||||||
|
if (theme === 'coal' || theme === 'navy') {
|
||||||
|
stylesheets.ayuHighlight.disabled = true;
|
||||||
|
stylesheets.tomorrowNight.disabled = false;
|
||||||
|
stylesheets.highlight.disabled = true;
|
||||||
|
|
||||||
|
ace_theme = 'ace/theme/tomorrow_night';
|
||||||
|
} else if (theme === 'ayu') {
|
||||||
|
stylesheets.ayuHighlight.disabled = false;
|
||||||
|
stylesheets.tomorrowNight.disabled = true;
|
||||||
|
stylesheets.highlight.disabled = true;
|
||||||
|
ace_theme = 'ace/theme/tomorrow_night';
|
||||||
|
} else {
|
||||||
|
stylesheets.ayuHighlight.disabled = true;
|
||||||
|
stylesheets.tomorrowNight.disabled = true;
|
||||||
|
stylesheets.highlight.disabled = false;
|
||||||
|
ace_theme = 'ace/theme/dawn';
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(function() {
|
||||||
|
themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor;
|
||||||
|
}, 1);
|
||||||
|
|
||||||
|
if (window.ace && window.editors) {
|
||||||
|
window.editors.forEach(function(editor) {
|
||||||
|
editor.setTheme(ace_theme);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (store) {
|
||||||
|
try {
|
||||||
|
localStorage.setItem('mdbook-theme', theme);
|
||||||
|
} catch (e) {
|
||||||
|
// ignore error.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
html.classList.remove(previousTheme);
|
||||||
|
html.classList.add(theme);
|
||||||
|
previousTheme = theme;
|
||||||
|
updateThemeSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
query.onchange = function() {
|
||||||
|
set_theme(get_theme(), false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set theme.
|
||||||
|
set_theme(get_theme(), false);
|
||||||
|
|
||||||
|
themeToggleButton.addEventListener('click', function() {
|
||||||
|
if (themePopup.style.display === 'block') {
|
||||||
|
hideThemes();
|
||||||
|
} else {
|
||||||
|
showThemes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
themePopup.addEventListener('click', function(e) {
|
||||||
|
let theme;
|
||||||
|
if (e.target.className === 'theme') {
|
||||||
|
theme = e.target.id;
|
||||||
|
} else if (e.target.parentElement.className === 'theme') {
|
||||||
|
theme = e.target.parentElement.id;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (theme === 'default_theme' || theme === null) {
|
||||||
|
delete_saved_theme();
|
||||||
|
set_theme(get_theme(), false);
|
||||||
|
} else {
|
||||||
|
set_theme(theme);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
themePopup.addEventListener('focusout', function(e) {
|
||||||
|
// e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
|
||||||
|
if (!!e.relatedTarget &&
|
||||||
|
!themeToggleButton.contains(e.relatedTarget) &&
|
||||||
|
!themePopup.contains(e.relatedTarget)
|
||||||
|
) {
|
||||||
|
hideThemes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Should not be needed, but it works around an issue on macOS & iOS:
|
||||||
|
// https://github.com/rust-lang/mdBook/issues/628
|
||||||
|
document.addEventListener('click', function(e) {
|
||||||
|
if (themePopup.style.display === 'block' &&
|
||||||
|
!themeToggleButton.contains(e.target) &&
|
||||||
|
!themePopup.contains(e.target)
|
||||||
|
) {
|
||||||
|
hideThemes();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('keydown', function(e) {
|
||||||
|
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!themePopup.contains(e.target)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let li;
|
||||||
|
switch (e.key) {
|
||||||
|
case 'Escape':
|
||||||
|
e.preventDefault();
|
||||||
|
hideThemes();
|
||||||
|
break;
|
||||||
|
case 'ArrowUp':
|
||||||
|
e.preventDefault();
|
||||||
|
li = document.activeElement.parentElement;
|
||||||
|
if (li && li.previousElementSibling) {
|
||||||
|
li.previousElementSibling.querySelector('button').focus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ArrowDown':
|
||||||
|
e.preventDefault();
|
||||||
|
li = document.activeElement.parentElement;
|
||||||
|
if (li && li.nextElementSibling) {
|
||||||
|
li.nextElementSibling.querySelector('button').focus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'Home':
|
||||||
|
e.preventDefault();
|
||||||
|
themePopup.querySelector('li:first-child button').focus();
|
||||||
|
break;
|
||||||
|
case 'End':
|
||||||
|
e.preventDefault();
|
||||||
|
themePopup.querySelector('li:last-child button').focus();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function sidebar() {
|
||||||
|
const body = document.querySelector('body');
|
||||||
|
const sidebar = document.getElementById('sidebar');
|
||||||
|
const sidebarLinks = document.querySelectorAll('#sidebar a');
|
||||||
|
const sidebarToggleButton = document.getElementById('sidebar-toggle');
|
||||||
|
const sidebarToggleAnchor = document.getElementById('sidebar-toggle-anchor');
|
||||||
|
const sidebarResizeHandle = document.getElementById('sidebar-resize-handle');
|
||||||
|
let firstContact = null;
|
||||||
|
|
||||||
|
function showSidebar() {
|
||||||
|
body.classList.remove('sidebar-hidden');
|
||||||
|
body.classList.add('sidebar-visible');
|
||||||
|
Array.from(sidebarLinks).forEach(function(link) {
|
||||||
|
link.setAttribute('tabIndex', 0);
|
||||||
|
});
|
||||||
|
sidebarToggleButton.setAttribute('aria-expanded', true);
|
||||||
|
sidebar.setAttribute('aria-hidden', false);
|
||||||
|
try {
|
||||||
|
localStorage.setItem('mdbook-sidebar', 'visible');
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore error.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideSidebar() {
|
||||||
|
body.classList.remove('sidebar-visible');
|
||||||
|
body.classList.add('sidebar-hidden');
|
||||||
|
Array.from(sidebarLinks).forEach(function(link) {
|
||||||
|
link.setAttribute('tabIndex', -1);
|
||||||
|
});
|
||||||
|
sidebarToggleButton.setAttribute('aria-expanded', false);
|
||||||
|
sidebar.setAttribute('aria-hidden', true);
|
||||||
|
try {
|
||||||
|
localStorage.setItem('mdbook-sidebar', 'hidden');
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore error.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle sidebar
|
||||||
|
sidebarToggleAnchor.addEventListener('change', function sidebarToggle() {
|
||||||
|
if (sidebarToggleAnchor.checked) {
|
||||||
|
const current_width = parseInt(
|
||||||
|
document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
|
||||||
|
if (current_width < 150) {
|
||||||
|
document.documentElement.style.setProperty('--sidebar-width', '150px');
|
||||||
|
}
|
||||||
|
showSidebar();
|
||||||
|
} else {
|
||||||
|
hideSidebar();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sidebarResizeHandle.addEventListener('mousedown', initResize, false);
|
||||||
|
|
||||||
|
function initResize() {
|
||||||
|
window.addEventListener('mousemove', resize, false);
|
||||||
|
window.addEventListener('mouseup', stopResize, false);
|
||||||
|
body.classList.add('sidebar-resizing');
|
||||||
|
}
|
||||||
|
function resize(e) {
|
||||||
|
let pos = e.clientX - sidebar.offsetLeft;
|
||||||
|
if (pos < 20) {
|
||||||
|
hideSidebar();
|
||||||
|
} else {
|
||||||
|
if (body.classList.contains('sidebar-hidden')) {
|
||||||
|
showSidebar();
|
||||||
|
}
|
||||||
|
pos = Math.min(pos, window.innerWidth - 100);
|
||||||
|
document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//on mouseup remove windows functions mousemove & mouseup
|
||||||
|
function stopResize() {
|
||||||
|
body.classList.remove('sidebar-resizing');
|
||||||
|
window.removeEventListener('mousemove', resize, false);
|
||||||
|
window.removeEventListener('mouseup', stopResize, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('touchstart', function(e) {
|
||||||
|
firstContact = {
|
||||||
|
x: e.touches[0].clientX,
|
||||||
|
time: Date.now(),
|
||||||
|
};
|
||||||
|
}, { passive: true });
|
||||||
|
|
||||||
|
document.addEventListener('touchmove', function(e) {
|
||||||
|
if (!firstContact) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const curX = e.touches[0].clientX;
|
||||||
|
const xDiff = curX - firstContact.x,
|
||||||
|
tDiff = Date.now() - firstContact.time;
|
||||||
|
|
||||||
|
if (tDiff < 250 && Math.abs(xDiff) >= 150) {
|
||||||
|
if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300)) {
|
||||||
|
showSidebar();
|
||||||
|
} else if (xDiff < 0 && curX < 300) {
|
||||||
|
hideSidebar();
|
||||||
|
}
|
||||||
|
|
||||||
|
firstContact = null;
|
||||||
|
}
|
||||||
|
}, { passive: true });
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function chapterNavigation() {
|
||||||
|
document.addEventListener('keydown', function(e) {
|
||||||
|
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (window.search && window.search.hasFocus()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const html = document.querySelector('html');
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
const nextButton = document.querySelector('.nav-chapters.next');
|
||||||
|
if (nextButton) {
|
||||||
|
window.location.href = nextButton.href;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function prev() {
|
||||||
|
const previousButton = document.querySelector('.nav-chapters.previous');
|
||||||
|
if (previousButton) {
|
||||||
|
window.location.href = previousButton.href;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (e.key) {
|
||||||
|
case 'ArrowRight':
|
||||||
|
e.preventDefault();
|
||||||
|
if (html.dir === 'rtl') {
|
||||||
|
prev();
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'ArrowLeft':
|
||||||
|
e.preventDefault();
|
||||||
|
if (html.dir === 'rtl') {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
prev();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function clipboard() {
|
||||||
|
const clipButtons = document.querySelectorAll('.clip-button');
|
||||||
|
|
||||||
|
function hideTooltip(elem) {
|
||||||
|
elem.firstChild.innerText = '';
|
||||||
|
elem.className = 'clip-button';
|
||||||
|
}
|
||||||
|
|
||||||
|
function showTooltip(elem, msg) {
|
||||||
|
elem.firstChild.innerText = msg;
|
||||||
|
elem.className = 'clip-button tooltipped';
|
||||||
|
}
|
||||||
|
|
||||||
|
const clipboardSnippets = new ClipboardJS('.clip-button', {
|
||||||
|
text: function(trigger) {
|
||||||
|
hideTooltip(trigger);
|
||||||
|
const playground = trigger.closest('pre');
|
||||||
|
return playground_text(playground, false);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Array.from(clipButtons).forEach(function(clipButton) {
|
||||||
|
clipButton.addEventListener('mouseout', function(e) {
|
||||||
|
hideTooltip(e.currentTarget);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboardSnippets.on('success', function(e) {
|
||||||
|
e.clearSelection();
|
||||||
|
showTooltip(e.trigger, 'Copied!');
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboardSnippets.on('error', function(e) {
|
||||||
|
showTooltip(e.trigger, 'Clipboard error!');
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function scrollToTop() {
|
||||||
|
const menuTitle = document.querySelector('.menu-title');
|
||||||
|
|
||||||
|
menuTitle.addEventListener('click', function() {
|
||||||
|
document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function controllMenu() {
|
||||||
|
const menu = document.getElementById('menu-bar');
|
||||||
|
|
||||||
|
(function controllPosition() {
|
||||||
|
let scrollTop = document.scrollingElement.scrollTop;
|
||||||
|
let prevScrollTop = scrollTop;
|
||||||
|
const minMenuY = -menu.clientHeight - 50;
|
||||||
|
// When the script loads, the page can be at any scroll (e.g. if you reforesh it).
|
||||||
|
menu.style.top = scrollTop + 'px';
|
||||||
|
// Same as parseInt(menu.style.top.slice(0, -2), but faster
|
||||||
|
let topCache = menu.style.top.slice(0, -2);
|
||||||
|
menu.classList.remove('sticky');
|
||||||
|
let stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
|
||||||
|
document.addEventListener('scroll', function() {
|
||||||
|
scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
|
||||||
|
// `null` means that it doesn't need to be updated
|
||||||
|
let nextSticky = null;
|
||||||
|
let nextTop = null;
|
||||||
|
const scrollDown = scrollTop > prevScrollTop;
|
||||||
|
const menuPosAbsoluteY = topCache - scrollTop;
|
||||||
|
if (scrollDown) {
|
||||||
|
nextSticky = false;
|
||||||
|
if (menuPosAbsoluteY > 0) {
|
||||||
|
nextTop = prevScrollTop;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (menuPosAbsoluteY > 0) {
|
||||||
|
nextSticky = true;
|
||||||
|
} else if (menuPosAbsoluteY < minMenuY) {
|
||||||
|
nextTop = prevScrollTop + minMenuY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nextSticky === true && stickyCache === false) {
|
||||||
|
menu.classList.add('sticky');
|
||||||
|
stickyCache = true;
|
||||||
|
} else if (nextSticky === false && stickyCache === true) {
|
||||||
|
menu.classList.remove('sticky');
|
||||||
|
stickyCache = false;
|
||||||
|
}
|
||||||
|
if (nextTop !== null) {
|
||||||
|
menu.style.top = nextTop + 'px';
|
||||||
|
topCache = nextTop;
|
||||||
|
}
|
||||||
|
prevScrollTop = scrollTop;
|
||||||
|
}, { passive: true });
|
||||||
|
})();
|
||||||
|
(function controllBorder() {
|
||||||
|
function updateBorder() {
|
||||||
|
if (menu.offsetTop === 0) {
|
||||||
|
menu.classList.remove('bordered');
|
||||||
|
} else {
|
||||||
|
menu.classList.add('bordered');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateBorder();
|
||||||
|
document.addEventListener('scroll', updateBorder, { passive: true });
|
||||||
|
})();
|
||||||
|
})();
|
7
clipboard.min.js
vendored
Normal file
7
clipboard.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
428
collections/hashmap.html
Normal file
428
collections/hashmap.html
Normal file
@ -0,0 +1,428 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>HashMap - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/collections/hashmap.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="hashmap"><a class="header" href="#hashmap">HashMap</a></h1>
|
||||||
|
<p>Where vectors store values by an integer index, HashMaps store values by key. It is a hash map implemented with quadratic probing and SIMD lookup. By default, <code>HashMap</code> uses a hashing algorithm selected to provide resistance against HashDoS attacks.</p>
|
||||||
|
<p>The default hashing algorithm is currently <code>SipHash 1-3</code>, though this is subject to change at any point in the future. While its performance is very competitive for medium sized keys, other hashing algorithms will outperform it for small keys such as integers as well as large keys such as long strings, though those algorithms will typically not protect against attacks such as HashDoS.</p>
|
||||||
|
<p>The hash table implementation is a Rust port of Google’s <a href="https://abseil.io/blog/20180927-swisstables">SwissTable</a>. The original C++ version of SwissTable can be found <a href="https://github.com/abseil/abseil-cpp/blob/master/absl/container/internal/raw_hash_set.h">here</a>, and this <a href="https://www.youtube.com/watch?v=ncHmEUmJZf4">CppCon talk</a> gives an overview of how the algorithm works.</p>
|
||||||
|
<h3 id="basic-operations"><a class="header" href="#basic-operations">Basic Operations</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blanks and FIX the errors
|
||||||
|
use std::collections::HashMap;
|
||||||
|
fn main() {
|
||||||
|
let mut scores = HashMap::new();
|
||||||
|
scores.insert("Sunface", 98);
|
||||||
|
scores.insert("Daniel", 95);
|
||||||
|
scores.insert("Ashley", 69.0);
|
||||||
|
scores.insert("Katie", "58");
|
||||||
|
|
||||||
|
// Get returns an Option<&V>
|
||||||
|
let score = scores.get("Sunface");
|
||||||
|
assert_eq!(score, Some(98));
|
||||||
|
|
||||||
|
if scores.contains_key("Daniel") {
|
||||||
|
// Indexing returns a value V
|
||||||
|
let score = scores["Daniel"];
|
||||||
|
assert_eq!(score, __);
|
||||||
|
scores.remove("Daniel");
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(scores.len(), __);
|
||||||
|
|
||||||
|
for (name, score) in scores {
|
||||||
|
println!("The score of {} is {}", name, score);
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
use std::collections::HashMap;
|
||||||
|
fn main() {
|
||||||
|
let teams = [
|
||||||
|
("Chinese Team", 100),
|
||||||
|
("American Team", 10),
|
||||||
|
("France Team", 50),
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut teams_map1 = HashMap::new();
|
||||||
|
for team in &teams {
|
||||||
|
teams_map1.insert(team.0, team.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMPLEMENT team_map2 in two ways
|
||||||
|
// Tips: one of the approaches is to use `collect` method
|
||||||
|
let teams_map2...
|
||||||
|
|
||||||
|
assert_eq!(teams_map1, teams_map2);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blanks
|
||||||
|
use std::collections::HashMap;
|
||||||
|
fn main() {
|
||||||
|
// Type inference lets us omit an explicit type signature (which
|
||||||
|
// would be `HashMap<&str, u8>` in this example).
|
||||||
|
let mut player_stats = HashMap::new();
|
||||||
|
|
||||||
|
// Insert a key only if it doesn't already exist
|
||||||
|
player_stats.entry("health").or_insert(100);
|
||||||
|
|
||||||
|
assert_eq!(player_stats["health"], __);
|
||||||
|
|
||||||
|
// Insert a key using a function that provides a new value only if it
|
||||||
|
// doesn't already exist
|
||||||
|
player_stats.entry("health").or_insert_with(random_stat_buff);
|
||||||
|
assert_eq!(player_stats["health"], __);
|
||||||
|
|
||||||
|
// Ensures a value is in the entry by inserting the default if empty, and returns
|
||||||
|
// a mutable reference to the value in the entry.
|
||||||
|
let health = player_stats.entry("health").or_insert(50);
|
||||||
|
assert_eq!(health, __);
|
||||||
|
*health -= 50;
|
||||||
|
assert_eq!(*health, __);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn random_stat_buff() -> u8 {
|
||||||
|
// Could actually return some random value here - let's just return
|
||||||
|
// some fixed value for now
|
||||||
|
42
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="requirements-of-hashmap-key"><a class="header" href="#requirements-of-hashmap-key">Requirements of HashMap key</a></h3>
|
||||||
|
<p>Any type that implements the <code>Eq</code> and <code>Hash</code> traits can be a key in <code>HashMap</code>. This includes:</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>bool</code> (though not very useful since there is only two possible keys)</li>
|
||||||
|
<li><code>int</code>, <code>uint</code>, and all variations thereof</li>
|
||||||
|
<li><code>String</code> and <code>&str</code> (tips: you can have a <code>HashMap</code> keyed by <code>String</code> and call <code>.get()</code> with an <code>&str</code>)</li>
|
||||||
|
</ul>
|
||||||
|
<p>Note that <code>f32</code> and <code>f64</code> do not implement <code>Hash</code>, likely because <a href="https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems">floating-point precision</a> errors would make using them as hashmap keys horribly error-prone.</p>
|
||||||
|
<p>All collection classes implement <code>Eq</code> and <code>Hash</code> if their contained type also respectively implements <code>Eq</code> and <code>Hash</code>. For example, <code>Vec<T></code> will implement <code>Hash</code> if <code>T</code>implements <code>Hash</code>.</p>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FIX the errors
|
||||||
|
// Tips: `derive` is usually a good way to implement some common used traits
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
struct Viking {
|
||||||
|
name: String,
|
||||||
|
country: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Viking {
|
||||||
|
/// Creates a new Viking.
|
||||||
|
fn new(name: &str, country: &str) -> Viking {
|
||||||
|
Viking {
|
||||||
|
name: name.to_string(),
|
||||||
|
country: country.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Use a HashMap to store the vikings' health points.
|
||||||
|
let vikings = HashMap::from([
|
||||||
|
(Viking::new("Einar", "Norway"), 25),
|
||||||
|
(Viking::new("Olaf", "Denmark"), 24),
|
||||||
|
(Viking::new("Harald", "Iceland"), 12),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Use derived implementation to print the status of the vikings.
|
||||||
|
for (viking, health) in &vikings {
|
||||||
|
println!("{:?} has {} hp", viking, health);
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="capacity"><a class="header" href="#capacity">Capacity</a></h3>
|
||||||
|
<p>Like vectors, HashMaps are growable, but HashMaps can also shrink themselves when they have excess space. You can create a <code>HashMap</code> with a certain starting capacity using <code>HashMap::with_capacity(uint)</code>, or use <code>HashMap::new()</code> to get a HashMap with a default initial capacity (recommended).</p>
|
||||||
|
<h4 id="example"><a class="header" href="#example">Example</a></h4>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
use std::collections::HashMap;
|
||||||
|
fn main() {
|
||||||
|
let mut map: HashMap<i32, i32> = HashMap::with_capacity(100);
|
||||||
|
map.insert(1, 2);
|
||||||
|
map.insert(3, 4);
|
||||||
|
// Indeed ,the capacity of HashMap is not 100, so we can't compare the equality here.
|
||||||
|
assert!(map.capacity() >= 100);
|
||||||
|
|
||||||
|
// Shrinks the capacity of the map with a lower limit. It will drop
|
||||||
|
// down no lower than the supplied limit while maintaining the internal rules
|
||||||
|
// and possibly leaving some space in accordance with the resize policy.
|
||||||
|
|
||||||
|
map.shrink_to(50);
|
||||||
|
assert!(map.capacity() >= 50);
|
||||||
|
|
||||||
|
// Shrinks the capacity of the map as much as possible. It will drop
|
||||||
|
// down as much as possible while maintaining the internal rules
|
||||||
|
// and possibly leaving some space in accordance with the resize policy.
|
||||||
|
map.shrink_to_fit();
|
||||||
|
assert!(map.capacity() >= 2);
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="ownership"><a class="header" href="#ownership">Ownership</a></h3>
|
||||||
|
<p>For types that implement the <code>Copy</code> trait, like <code>i32</code> , the values are copied into <code>HashMap</code>. For owned values like <code>String</code>, the values will be moved and <code>HashMap</code> will be the owner of those values.</p>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// FIX the errors with least changes
|
||||||
|
// DON'T remove any code line
|
||||||
|
use std::collections::HashMap;
|
||||||
|
fn main() {
|
||||||
|
let v1 = 10;
|
||||||
|
let mut m1 = HashMap::new();
|
||||||
|
m1.insert(v1, v1);
|
||||||
|
println!("v1 is still usable after inserting to hashmap : {}", v1);
|
||||||
|
|
||||||
|
let v2 = "hello".to_string();
|
||||||
|
let mut m2 = HashMap::new();
|
||||||
|
// Ownership moved here
|
||||||
|
m2.insert(v2, v1);
|
||||||
|
|
||||||
|
assert_eq!(v2, "hello");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="third-party-hash-libs"><a class="header" href="#third-party-hash-libs">Third-party Hash libs</a></h3>
|
||||||
|
<p>If the performance of <code>SipHash 1-3</code> doesn't meet your requirements, you can find replacements in crates.io or github.com.</p>
|
||||||
|
<p>The usage of third-party hash looks like this:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>use std::hash::BuildHasherDefault;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
// Introduce a third party hash function
|
||||||
|
use twox_hash::XxHash64;
|
||||||
|
|
||||||
|
|
||||||
|
let mut hash: HashMap<_, _, BuildHasherDefault<XxHash64>> = Default::default();
|
||||||
|
hash.insert(42, "the answer");
|
||||||
|
assert_eq!(hash.get(&42), Some(&"the answer"));
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../collections/vector.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="../type-conversions/intro.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="../collections/vector.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="../type-conversions/intro.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
229
collections/intro.html
Normal file
229
collections/intro.html
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Collection Types - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/collections/intro.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="collection-types"><a class="header" href="#collection-types">Collection Types</a></h1>
|
||||||
|
<p>Learning resources:</p>
|
||||||
|
<ul>
|
||||||
|
<li>English: <a href="https://doc.rust-lang.org/book/ch08-00-common-collections.html">Rust Book Chapter 8</a></li>
|
||||||
|
<li>简体中文: <a href="https://course.rs/basic/collections/intro.html">Rust语言圣经 - 集合类型</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../generics-traits/advanced-traits.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="../collections/string.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="../generics-traits/advanced-traits.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="../collections/string.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
410
collections/string.html
Normal file
410
collections/string.html
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>String - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/collections/string.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="string"><a class="header" href="#string">String</a></h1>
|
||||||
|
<p><code>std::string::String</code> is a UTF-8 encoded, growable string. It is the most common string type we used in daily development, it also has ownership over the string contents.</p>
|
||||||
|
<h3 id="basic-operations"><a class="header" href="#basic-operations">Basic operations</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blanks and FIX errors
|
||||||
|
// 1. Don't use `to_string()`
|
||||||
|
// 2. Don't add/remove any code line
|
||||||
|
fn main() {
|
||||||
|
let mut s: String = "hello, ";
|
||||||
|
s.push_str("world".to_string());
|
||||||
|
s.push(__);
|
||||||
|
|
||||||
|
move_ownership(s);
|
||||||
|
|
||||||
|
assert_eq!(s, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_ownership(s: String) {
|
||||||
|
println!("ownership of \"{}\" is moved here!", s)
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="string-and-str"><a class="header" href="#string-and-str">String and &str</a></h3>
|
||||||
|
<p>A <code>String</code> is stored as a vector of bytes (<code>Vec<u8></code>), but guaranteed to always be a valid UTF-8 sequence. <code>String</code> is heap allocated, growable and not null terminated.</p>
|
||||||
|
<p><code>&str</code> is a slice (<code>&[u8]</code>) that always points to a valid UTF-8 sequence, and can be used to view into a String, just like <code>&[T]</code> is a view into <code>Vec<T></code>.</p>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// FILL in the blanks
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello, world");
|
||||||
|
|
||||||
|
let slice1: &str = __; // In two ways
|
||||||
|
assert_eq!(slice1, "hello, world");
|
||||||
|
|
||||||
|
let slice2 = __;
|
||||||
|
assert_eq!(slice2, "hello");
|
||||||
|
|
||||||
|
let slice3: __ = __;
|
||||||
|
slice3.push('!');
|
||||||
|
assert_eq!(slice3, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Question: how many heap allocations are happening here?
|
||||||
|
// Your answer:
|
||||||
|
fn main() {
|
||||||
|
// Create a String type based on `&str`
|
||||||
|
// The type of string literals is `&str`
|
||||||
|
let s: String = String::from("hello, world!");
|
||||||
|
|
||||||
|
// Create a slice point to String `s`
|
||||||
|
let slice: &str = &s;
|
||||||
|
|
||||||
|
// Create a String type based on the recently created slice
|
||||||
|
let s: String = slice.to_string();
|
||||||
|
|
||||||
|
assert_eq!(s, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="utf-8--indexing"><a class="header" href="#utf-8--indexing">UTF-8 & Indexing</a></h3>
|
||||||
|
<p>Strings are always valid UTF-8. This has a few implications:</p>
|
||||||
|
<ul>
|
||||||
|
<li>The first of which is that if you need a non-UTF-8 string, consider <a href="https://doc.rust-lang.org/stable/std/ffi/struct.OsString.html">OsString</a>. It is similar, but without the UTF-8 constraint.</li>
|
||||||
|
<li>The second implication is that you cannot index into a String.</li>
|
||||||
|
</ul>
|
||||||
|
<p>Indexing is intended to be a constant-time operation, but UTF-8 encoding does not allow us to do this. Furthermore, it’s not clear what sort of thing the index should return: a byte, a codepoint, or a grapheme cluster. The bytes and chars methods return iterators over the first two, respectively.</p>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟🌟 You can't use index to access a char in a string, but you can use slice <code>&s1[start..end]</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blank and FIX errors
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("hello, 世界");
|
||||||
|
let slice1 = s[0]; //tips: `h` only takes 1 byte in UTF8 format
|
||||||
|
assert_eq!(slice1, "h");
|
||||||
|
|
||||||
|
let slice2 = &s[3..5]; // Tips: `中` takes 3 bytes in UTF8 format
|
||||||
|
assert_eq!(slice2, "世");
|
||||||
|
|
||||||
|
// Iterate through all chars in s
|
||||||
|
for (i, c) in s.__ {
|
||||||
|
if i == 7 {
|
||||||
|
assert_eq!(c, '世')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="utf8_slice"><a class="header" href="#utf8_slice">UTF8_slice</a></h4>
|
||||||
|
<p>You can use <a href="https://docs.rs/utf8_slice/1.0.0/utf8_slice/fn.slice.html">utf8_slice</a> to slice UTF8 string, it can index chars instead of bytes.</p>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">use utf8_slice;
|
||||||
|
fn main() {
|
||||||
|
let s = "The 🚀 goes to the 🌑!";
|
||||||
|
|
||||||
|
let rocket = utf8_slice::slice(s, 4, 5);
|
||||||
|
// Will equal "🚀"
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<blockquote>
|
||||||
|
<p>Tips: maybe you need <code>from_utf8</code> method</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blanks
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::new();
|
||||||
|
__;
|
||||||
|
|
||||||
|
// Some bytes, in a vector
|
||||||
|
let v = vec![104, 101, 108, 108, 111];
|
||||||
|
|
||||||
|
// Turn a byte's vector into a String
|
||||||
|
let s1 = __;
|
||||||
|
|
||||||
|
|
||||||
|
assert_eq!(s, s1);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="representation"><a class="header" href="#representation">Representation</a></h3>
|
||||||
|
<p>A String is made up of three components: a pointer to some bytes, a length, and a capacity.</p>
|
||||||
|
<p>The pointer points to an internal buffer String uses to store its data. The length is the number of bytes currently stored in the buffer( always stored on the heap ), and the capacity is the size of the buffer in bytes. As such, the length will always be less than or equal to the capacity.</p>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟 If a String has enough capacity, adding elements to it will not re-allocate</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Modify the code below to print out:
|
||||||
|
// 25
|
||||||
|
// 25
|
||||||
|
// 25
|
||||||
|
// Here, there’s no need to allocate more memory inside the loop.
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::new();
|
||||||
|
|
||||||
|
println!("{}", s.capacity());
|
||||||
|
|
||||||
|
for _ in 0..2 {
|
||||||
|
s.push_str("hello");
|
||||||
|
println!("{}", s.capacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blanks
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let story = String::from("Rust By Practice");
|
||||||
|
|
||||||
|
// Prevent automatically dropping of the String's data
|
||||||
|
let mut story = mem::ManuallyDrop::new(story);
|
||||||
|
|
||||||
|
let ptr = story.__();
|
||||||
|
let len = story.__();
|
||||||
|
let capacity = story.__();
|
||||||
|
|
||||||
|
assert_eq!(16, len);
|
||||||
|
|
||||||
|
// We can rebuild a String out of ptr, len, and capacity. This is all
|
||||||
|
// unsafe because we are responsible for making sure the components are
|
||||||
|
// valid:
|
||||||
|
let s = unsafe { String::from_raw_parts(ptr, len, capacity) };
|
||||||
|
|
||||||
|
assert_eq!(*story, s);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="common-methods"><a class="header" href="#common-methods">Common methods</a></h3>
|
||||||
|
<p>More exercises of String methods can be found <a href="../std/String.html">here</a>.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../collections/intro.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="../collections/vector.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="../collections/intro.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="../collections/vector.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
451
collections/vector.html
Normal file
451
collections/vector.html
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Vector - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/collections/vector.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="vector"><a class="header" href="#vector">Vector</a></h1>
|
||||||
|
<p>Vectors are resizable arrays. Like slices, their size is not known at compile time, but they can grow or shrink at any time.</p>
|
||||||
|
<h3 id="basic-operations"><a class="header" href="#basic-operations">Basic Operations</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let arr: [u8; 3] = [1, 2, 3];
|
||||||
|
|
||||||
|
let v = Vec::from(arr);
|
||||||
|
is_vec(&v);
|
||||||
|
|
||||||
|
let v = vec![1, 2, 3];
|
||||||
|
is_vec(&v);
|
||||||
|
|
||||||
|
// vec!(..) and vec![..] are same macros, so
|
||||||
|
let v = vec!(1, 2, 3);
|
||||||
|
is_vec(&v);
|
||||||
|
|
||||||
|
// In code below, v is Vec<[u8; 3]> , not Vec<u8>
|
||||||
|
// USE Vec::new and `for` to rewrite the below code
|
||||||
|
let v1 = vec!(arr);
|
||||||
|
is_vec(&v1);
|
||||||
|
|
||||||
|
assert_eq!(v, v1);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_vec(v: &Vec<u8>) {}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟 A Vec can be extended with <code>extend</code> method</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blank
|
||||||
|
fn main() {
|
||||||
|
let mut v1 = Vec::from([1, 2, 4]);
|
||||||
|
v1.pop();
|
||||||
|
v1.push(3);
|
||||||
|
|
||||||
|
let mut v2 = Vec::new();
|
||||||
|
v2.__;
|
||||||
|
|
||||||
|
assert_eq!(v1, v2);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="turn-x-into-vec"><a class="header" href="#turn-x-into-vec">Turn X Into Vec</a></h3>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blanks
|
||||||
|
fn main() {
|
||||||
|
// Array -> Vec
|
||||||
|
// impl From<[T; N]> for Vec
|
||||||
|
let arr = [1, 2, 3];
|
||||||
|
let v1 = __(arr);
|
||||||
|
let v2: Vec<i32> = arr.__();
|
||||||
|
|
||||||
|
assert_eq!(v1, v2);
|
||||||
|
|
||||||
|
|
||||||
|
// String -> Vec
|
||||||
|
// impl From<String> for Vec
|
||||||
|
let s = "hello".to_string();
|
||||||
|
let v1: Vec<u8> = s.__();
|
||||||
|
|
||||||
|
let s = "hello".to_string();
|
||||||
|
let v2 = s.into_bytes();
|
||||||
|
assert_eq!(v1, v2);
|
||||||
|
|
||||||
|
// impl<'_> From<&'_ str> for Vec
|
||||||
|
let s = "hello";
|
||||||
|
let v3 = Vec::__(s);
|
||||||
|
assert_eq!(v2, v3);
|
||||||
|
|
||||||
|
// Iterators can be collected into vectors
|
||||||
|
let v4: Vec<i32> = [0; 10].into_iter().collect();
|
||||||
|
assert_eq!(v4, vec![0; 10]);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="indexing"><a class="header" href="#indexing">Indexing</a></h3>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FIX the error and IMPLEMENT the code
|
||||||
|
fn main() {
|
||||||
|
let mut v = Vec::from([1, 2, 3]);
|
||||||
|
for i in 0..5 {
|
||||||
|
println!("{:?}", v[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..5 {
|
||||||
|
// IMPLEMENT the code here...
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(v, vec![2, 3, 4, 5, 6]);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="slicing"><a class="header" href="#slicing">Slicing</a></h3>
|
||||||
|
<p>Immutable or mutable slices of Vecs can be taken, using <code>&</code> or <code>&mut</code>, respectively.</p>
|
||||||
|
<p>In Rust, it’s more common to pass immutable slices as arguments rather than vectors when you just want to provide read access, as this is more flexible (no move) and efficient (no copy). The same goes for <code>String</code> and <code>&str</code>.</p>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FIX the errors
|
||||||
|
fn main() {
|
||||||
|
let mut v = vec![1, 2, 3];
|
||||||
|
|
||||||
|
let slice1 = &v[..];
|
||||||
|
// Out of bounds will cause a panic
|
||||||
|
// You must use `v.len` here
|
||||||
|
let slice2 = &v[0..4];
|
||||||
|
|
||||||
|
assert_eq!(slice1, slice2);
|
||||||
|
|
||||||
|
// A slice can also be mutable, in which
|
||||||
|
// case mutating it will mutate its underlying Vec.
|
||||||
|
// Note: slice and &Vec are different
|
||||||
|
let vec_ref: &mut Vec<i32> = &mut v;
|
||||||
|
(*vec_ref).push(4);
|
||||||
|
let slice3 = &mut v[0..3];
|
||||||
|
slice3[3] = 42;
|
||||||
|
|
||||||
|
assert_eq!(slice3, &[1, 2, 3, 42]);
|
||||||
|
assert_eq!(v, &[1, 2, 3, 42]);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="capacity"><a class="header" href="#capacity">Capacity</a></h3>
|
||||||
|
<p>The capacity of a vector is the amount of space allocated for any future elements that will be added onto the vector. This is not to be confused with the length of a vector, which specifies the number of actual elements within the vector. If a vector’s length exceeds its capacity, its capacity will automatically be increased, but its elements will have to be reallocated.</p>
|
||||||
|
<p>For example, a vector with capacity 10 and length 0 would be an empty vector with space for 10 more elements. Pushing 10 or fewer elements onto the vector will not change its capacity or cause reallocation to occur. However, if the vector’s length is increased to 11, it will have to reallocate, which can be slow. For this reason, it is recommended to use <code>Vec::with_capacity </code>whenever possible to specify how big the vector is expected to get.</p>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// FIX the errors
|
||||||
|
fn main() {
|
||||||
|
let mut vec = Vec::with_capacity(10);
|
||||||
|
|
||||||
|
// The vector contains no items, even though it has capacity for more
|
||||||
|
assert_eq!(vec.len(), __);
|
||||||
|
assert_eq!(vec.capacity(), 10);
|
||||||
|
|
||||||
|
// These are all done without reallocating...
|
||||||
|
for i in 0..10 {
|
||||||
|
vec.push(i);
|
||||||
|
}
|
||||||
|
assert_eq!(vec.len(), __);
|
||||||
|
assert_eq!(vec.capacity(), __);
|
||||||
|
|
||||||
|
// ...but this may make the vector reallocate
|
||||||
|
vec.push(11);
|
||||||
|
assert_eq!(vec.len(), 11);
|
||||||
|
assert!(vec.capacity() >= 11);
|
||||||
|
|
||||||
|
|
||||||
|
// Fill in an appropriate value to make the `for` done without reallocating
|
||||||
|
let mut vec = Vec::with_capacity(__);
|
||||||
|
for i in 0..100 {
|
||||||
|
vec.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(vec.len(), __);
|
||||||
|
assert_eq!(vec.capacity(), __);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="store-distinct-types-in-vector"><a class="header" href="#store-distinct-types-in-vector">Store distinct types in Vector</a></h3>
|
||||||
|
<p>The elements in a vector must be the same type, for example , the code below will cause an error:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
let v = vec![1, 2.0, 3];
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>But we can use enums or trait objects to store distinct types.</p>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">#[derive(Debug)]
|
||||||
|
enum IpAddr {
|
||||||
|
V4(String),
|
||||||
|
V6(String),
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
// FILL in the blank
|
||||||
|
let v : Vec<IpAddr>= __;
|
||||||
|
|
||||||
|
// Comparing two enums need to derive the PartialEq trait
|
||||||
|
assert_eq!(v[0], IpAddr::V4("127.0.0.1".to_string()));
|
||||||
|
assert_eq!(v[1], IpAddr::V6("::1".to_string()));
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">trait IpAddr {
|
||||||
|
fn display(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct V4(String);
|
||||||
|
impl IpAddr for V4 {
|
||||||
|
fn display(&self) {
|
||||||
|
println!("ipv4: {:?}",self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct V6(String);
|
||||||
|
impl IpAddr for V6 {
|
||||||
|
fn display(&self) {
|
||||||
|
println!("ipv6: {:?}",self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// FILL in the blank
|
||||||
|
let v: __= vec![
|
||||||
|
Box::new(V4("127.0.0.1".to_string())),
|
||||||
|
Box::new(V6("::1".to_string())),
|
||||||
|
];
|
||||||
|
|
||||||
|
for ip in v {
|
||||||
|
ip.display();
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../collections/string.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="../collections/hashmap.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="../collections/string.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="../collections/hashmap.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
488
comments-docs.html
Normal file
488
comments-docs.html
Normal file
@ -0,0 +1,488 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Comments and Docs - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/comments-docs.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="comments-and-docs"><a class="header" href="#comments-and-docs">Comments and Docs</a></h1>
|
||||||
|
<p>Every program requires comments:</p>
|
||||||
|
<h2 id="comments"><a class="header" href="#comments">Comments</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Regular comments which are ignored by the compiler:
|
||||||
|
<ul>
|
||||||
|
<li><code>// Line comment, which goes to the end of the line</code></li>
|
||||||
|
<li><code>/* Block comment, which goes to the end of the closing delimiter */</code></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h3 id="examples"><a class="header" href="#examples">Examples</a></h3>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
// This is an example of a line comment
|
||||||
|
// There are two slashes at the beginning of the line
|
||||||
|
// And nothing written inside these will be read by the compiler
|
||||||
|
|
||||||
|
// println!("Hello, world!");
|
||||||
|
|
||||||
|
// Run it. See? Now try deleting the two slashes, and run it again.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is another type of comment, a block comment. In general,
|
||||||
|
* line comments are the recommended comment style. But
|
||||||
|
* block comments are extremely useful for temporarily disabling
|
||||||
|
* chunks of code. /* Block comments can be /* nested, */ */
|
||||||
|
* so it takes only a few keystrokes to comment out everything
|
||||||
|
* in this main() function. /*/*/* Try it yourself! */*/*/
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note: The previous column of `*` was entirely for style. There's
|
||||||
|
no actual need for it.
|
||||||
|
*/
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="exercises"><a class="header" href="#exercises">Exercises</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
/* Make it work, only using comments! */
|
||||||
|
fn main() {
|
||||||
|
todo!();
|
||||||
|
unimplemented!();
|
||||||
|
|
||||||
|
assert_eq!(6, 5 + 3 + 2 + 1 )
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="doc-comments"><a class="header" href="#doc-comments">Doc Comments</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Doc comments which are parsed into HTML and supported <code>Markdown</code>
|
||||||
|
<ul>
|
||||||
|
<li><code>/// Generate library docs for the following item</code></li>
|
||||||
|
<li><code>//! Generate library docs for the eclosing item</code></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Before starting, we need to create a new package for practice: <code>cargo new --lib doc-comments</code>.</p>
|
||||||
|
<h3 id="line-doc-comments-"><a class="header" href="#line-doc-comments-">Line doc comments <code>///</code></a></h3>
|
||||||
|
<p>Add docs for function <code>add_one</code></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>// in lib.rs
|
||||||
|
|
||||||
|
/// Add one to the given value and return the value
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let arg = 5;
|
||||||
|
/// let answer = my_crate::add_one(arg);
|
||||||
|
///
|
||||||
|
/// assert_eq!(6, answer);
|
||||||
|
/// ```
|
||||||
|
pub fn add_one(x: i32) -> i32 {
|
||||||
|
x + 1
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<h3 id="cargo-doc"><a class="header" href="#cargo-doc">Cargo doc</a></h3>
|
||||||
|
<p>We can use <code>cargo doc --open</code> to generate html files and open them in the browser.</p>
|
||||||
|
<h3 id="block-doc-comments---"><a class="header" href="#block-doc-comments---">Block doc comments <code>/** ... */</code></a></h3>
|
||||||
|
<p>Add docs for function <code>add_two</code>:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>/** Add two to the given value and return a new value
|
||||||
|
|
||||||
|
<span class="boring">Examples
|
||||||
|
</span>
|
||||||
|
let arg = 5;
|
||||||
|
let answer = my_crate::add_two(arg);
|
||||||
|
|
||||||
|
assert_eq!(7, answer);
|
||||||
|
|
||||||
|
*/
|
||||||
|
pub fn add_two(x: i32) -> i32 {
|
||||||
|
x + 2
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<h3 id="doc-comments-for-crate-and-module"><a class="header" href="#doc-comments-for-crate-and-module">Doc comments for crate and module</a></h3>
|
||||||
|
<p>We can also add doc comments for our crates and modules.</p>
|
||||||
|
<p>Firstly, let's add some doc comments for our library crate:</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>Note: We must place crates and module comments at the top of crate root or module file.</p>
|
||||||
|
</blockquote>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>//! # Doc comments
|
||||||
|
//!
|
||||||
|
//! A library for showing how to use doc comments
|
||||||
|
|
||||||
|
// in lib.rs
|
||||||
|
pub mod compute;
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>You can also use block comments to achieve this:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>/*! # Doc comments
|
||||||
|
|
||||||
|
A library for showing how to use doc comments */
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>Next, create a new module file <code>src/compute.rs</code>, and add following comments to it:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>//! //! Do some complicated arithmetic that you can't do by yourself
|
||||||
|
|
||||||
|
// in compute.rs
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>Then run <code>cargo doc --open</code> and see the results.</p>
|
||||||
|
<h3 id="doc-tests"><a class="header" href="#doc-tests">Doc tests</a></h3>
|
||||||
|
<p>The doc comments of <code>add_one</code> and <code>add_two</code> contain two example code blocks.</p>
|
||||||
|
<p>The examples can not only demonstrate how to use your library, but also running as test with <code>cargo test</code> command.</p>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟 But there are errors in the two examples, please fix them, and running with <code>cargo test</code> to get following result:</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="language-shell">running 0 tests
|
||||||
|
|
||||||
|
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||||
|
|
||||||
|
Doc-tests doc-comments
|
||||||
|
|
||||||
|
running 2 tests
|
||||||
|
test src/lib.rs - add_one (line 11) ... ok
|
||||||
|
test src/lib.rs - add_two (line 26) ... ok
|
||||||
|
|
||||||
|
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.55s
|
||||||
|
</code></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟 Sometimes we expect an example to be panic, add following code to <code>src/compute.rs</code> and make the <code>cargo test</code> passed.</li>
|
||||||
|
</ol>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can only modify the comments, DON'T modify <code>fn div</code></p>
|
||||||
|
</blockquote>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>// in src/compute.rs
|
||||||
|
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// The function panics if the second argument is zero.
|
||||||
|
///
|
||||||
|
/// ```rust,should_panic
|
||||||
|
/// // panics on division by zero
|
||||||
|
/// doc_comments::compute::div(10, 0);
|
||||||
|
/// ```
|
||||||
|
pub fn div(a: i32, b: i32) -> i32 {
|
||||||
|
if b == 0 {
|
||||||
|
panic!("Divide-by-zero error");
|
||||||
|
}
|
||||||
|
|
||||||
|
a / b
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟 Sometimes we want to hide the doc comments, but keep the doc tests.</li>
|
||||||
|
</ol>
|
||||||
|
<p>Add following code to <code>src/compute.rs</code> ,</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">// in src/compute.rs
|
||||||
|
|
||||||
|
/// ```
|
||||||
|
/// # fn try_main() -> Result<(), String> {
|
||||||
|
/// # let res = doc_comments::compute::try_div(10, 0)?;
|
||||||
|
/// # Ok(()) // returning from try_main
|
||||||
|
/// # }
|
||||||
|
/// # fn main() {
|
||||||
|
/// # try_main().unwrap();
|
||||||
|
/// #
|
||||||
|
/// # }
|
||||||
|
/// ```
|
||||||
|
pub fn try_div(a: i32, b: i32) -> Result<i32, String> {
|
||||||
|
if b == 0 {
|
||||||
|
Err(String::from("Divide-by-zero"))
|
||||||
|
} else {
|
||||||
|
Ok(a / b)
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>and modify this code to achieve two goals:</p>
|
||||||
|
<ul>
|
||||||
|
<li>The doc comments must not be presented in html files generated by <code>cargo doc --open</code></li>
|
||||||
|
<li>run the tests, you should see results as below:</li>
|
||||||
|
</ul>
|
||||||
|
<pre><code class="language-shell">running 0 tests
|
||||||
|
|
||||||
|
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||||
|
|
||||||
|
Doc-tests doc-comments
|
||||||
|
|
||||||
|
running 4 tests
|
||||||
|
test src/compute.rs - compute::div (line 7) ... ok
|
||||||
|
test src/lib.rs - add_two (line 27) ... ok
|
||||||
|
test src/lib.rs - add_one (line 11) ... ok
|
||||||
|
test src/compute.rs - compute::try_div (line 20) ... ok
|
||||||
|
|
||||||
|
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.51s
|
||||||
|
</code></pre>
|
||||||
|
<h3 id="code-navigation"><a class="header" href="#code-navigation">Code navigation</a></h3>
|
||||||
|
<p>Rust provide a very powerful feature for us, that is code navigation in doc comments.</p>
|
||||||
|
<p>Add following code to <code>src/lib.rs</code>:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>// in lib.rs
|
||||||
|
|
||||||
|
/// Add three to the given value and return a [`Option`] type
|
||||||
|
pub fn add_three(x: i32) -> Option<i32> {
|
||||||
|
Some(x + 3)
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>Besides jump into the standard library, you can also jump to another module in the package.</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>// in lib.rs
|
||||||
|
|
||||||
|
mod a {
|
||||||
|
/// Add four to the given value and return a [`Option`] type
|
||||||
|
/// [`crate::MySpecialFormatter`]
|
||||||
|
pub fn add_four(x: i32) -> Option<i32> {
|
||||||
|
Some(x + 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MySpecialFormatter;
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<h3 id="doc-attributes"><a class="header" href="#doc-attributes">Doc attributes</a></h3>
|
||||||
|
<p>Below are a few examples of the most common <code>#[doc]</code> attributes used with <code>rustdoc</code>.</p>
|
||||||
|
<h3 id="inline"><a class="header" href="#inline"><code>inline</code></a></h3>
|
||||||
|
<p>Used to inline docs, instead of linking out to separate page.</p>
|
||||||
|
<pre><code class="language-rust ignore">#[doc(inline)]
|
||||||
|
pub use bar::Bar;
|
||||||
|
|
||||||
|
/// bar docs
|
||||||
|
mod bar {
|
||||||
|
/// the docs for Bar
|
||||||
|
pub struct Bar;
|
||||||
|
}</code></pre>
|
||||||
|
<h3 id="no_inline"><a class="header" href="#no_inline"><code>no_inline</code></a></h3>
|
||||||
|
<p>Used to prevent linking out to separate page or anywhere.</p>
|
||||||
|
<pre><code class="language-rust ignore">// Example from libcore/prelude
|
||||||
|
#[doc(no_inline)]
|
||||||
|
pub use crate::mem::drop;</code></pre>
|
||||||
|
<h3 id="hidden"><a class="header" href="#hidden"><code>hidden</code></a></h3>
|
||||||
|
<p>Using this tells <code>rustdoc</code> not to include this in documentation:</p>
|
||||||
|
<pre><code class="language-rust editable ignore">// Example from the futures-rs library
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub use self::async_await::*;</code></pre>
|
||||||
|
<p>For documentation, <code>rustdoc</code> is widely used by the community. It's what is used to generate the <a href="https://doc.rust-lang.org/std/">std library docs</a>.</p>
|
||||||
|
<h3 id="full-code"><a class="header" href="#full-code">Full Code</a></h3>
|
||||||
|
<p>The full code of package <code>doc-comments</code> is <a href="https://github.com/sunface/rust-by-practice/tree/master/practices/doc-comments">here</a>.</p>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="crate-module/use-pub.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="formatted-output/intro.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="crate-module/use-pub.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="formatted-output/intro.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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
318
compound-types/array.html
Normal file
318
compound-types/array.html
Normal file
@ -0,0 +1,318 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Array - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/compound-types/array.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="array"><a class="header" href="#array">Array</a></h1>
|
||||||
|
<p>The type of array is <code>[T; Length]</code>, as you can see, array's length is part of their type signature. So their length must be known at compile time.</p>
|
||||||
|
<p>For example, you cant initialize an array like below:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>fn init_arr(n: i32) {
|
||||||
|
let arr = [1; n];
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>This will cause an error, because the compiler has no idea of the exact size of the array at compile time.</p>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// Fill the blank with proper array type
|
||||||
|
let arr: __ = [1, 2, 3, 4, 5];
|
||||||
|
|
||||||
|
// Modify the code below to make it work
|
||||||
|
assert!(arr.len() == 4);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// We can ignore parts of the array type or even the whole type, let the compiler infer it for us
|
||||||
|
let arr0 = [1, 2, 3];
|
||||||
|
let arr: [_; 3] = ['a', 'b', 'c'];
|
||||||
|
|
||||||
|
// Fill the blank
|
||||||
|
// Arrays are stack allocated, `std::mem::size_of_val` returns the bytes which an array occupies
|
||||||
|
// A char takes 4 bytes in Rust: Unicode char
|
||||||
|
assert!(std::mem::size_of_val(&arr) == __);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟 All elements in an array can be initialized to the same value at once.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// Fill the blank
|
||||||
|
let list: [i32; 100] = __ ;
|
||||||
|
|
||||||
|
assert!(list[0] == 1);
|
||||||
|
assert!(list.len() == 100);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟 All elements in an array must be of the same type</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// Fix the error
|
||||||
|
let _arr = [1, 2, '3'];
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟 Indexing starts at 0.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let arr = ['a', 'b', 'c'];
|
||||||
|
|
||||||
|
let ele = arr[1]; // Only modify this line to make the code work!
|
||||||
|
|
||||||
|
assert!(ele == 'a');
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟 Out of bounds indexing causes <code>panic</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the error
|
||||||
|
fn main() {
|
||||||
|
let names = [String::from("Sunfei"), "Sunface".to_string()];
|
||||||
|
|
||||||
|
// `Get` returns an Option<&T>, it's safe to use
|
||||||
|
let name0 = names.get(0).unwrap();
|
||||||
|
|
||||||
|
// But indexing is not safe
|
||||||
|
let _name1 = &names[2];
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/array.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../compound-types/string.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="../compound-types/slice.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="../compound-types/string.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="../compound-types/slice.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
426
compound-types/enum.html
Normal file
426
compound-types/enum.html
Normal file
@ -0,0 +1,426 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Enum - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/compound-types/enum.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="enum"><a class="header" href="#enum">Enum</a></h1>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟 Enums can be created with explicit discriminator.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the errors
|
||||||
|
enum Number {
|
||||||
|
Zero,
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Number1 {
|
||||||
|
Zero = 0,
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
}
|
||||||
|
|
||||||
|
// C-like enum
|
||||||
|
enum Number2 {
|
||||||
|
Zero = 0.0,
|
||||||
|
One = 1.0,
|
||||||
|
Two = 2.0,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// An enum variant can be converted to a integer by `as`
|
||||||
|
assert_eq!(Number::One, Number1::One);
|
||||||
|
assert_eq!(Number1::One, Number2::One);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟 Each enum variant can hold its own data.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blank
|
||||||
|
enum Message {
|
||||||
|
Quit,
|
||||||
|
Move { x: i32, y: i32 },
|
||||||
|
Write(String),
|
||||||
|
ChangeColor(i32, i32, i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let msg1 = Message::Move{__}; // Instantiating with x = 1, y = 2
|
||||||
|
let msg2 = Message::Write(__); // Instantiating with "hello, world!"
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟 We can get the data which an enum variant is holding by pattern match.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blank and fix the error
|
||||||
|
enum Message {
|
||||||
|
Quit,
|
||||||
|
Move { x: i32, y: i32 },
|
||||||
|
Write(String),
|
||||||
|
ChangeColor(i32, i32, i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let msg = Message::Move{x: 1, y: 2};
|
||||||
|
|
||||||
|
if let Message::Move{__} = msg {
|
||||||
|
assert_eq!(a, b);
|
||||||
|
} else {
|
||||||
|
panic!("NEVER LET THIS RUN!");
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blank and fix the errors
|
||||||
|
enum Message {
|
||||||
|
Quit,
|
||||||
|
Move { x: i32, y: i32 },
|
||||||
|
Write(String),
|
||||||
|
ChangeColor(i32, i32, i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let msgs: __ = [
|
||||||
|
Message::Quit,
|
||||||
|
Message::Move{x:1, y:3},
|
||||||
|
Message::ChangeColor(255,255,0)
|
||||||
|
];
|
||||||
|
|
||||||
|
for msg in msgs {
|
||||||
|
show_message(msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_message(msg: Message) {
|
||||||
|
println!("{}", msg);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟 Since there is no <code>null</code> in Rust, we have to use enum <code>Option<T></code> to deal with the cases when the value is absent.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blank to make the `println` work.
|
||||||
|
// Also add some code to prevent the `panic` from running.
|
||||||
|
fn main() {
|
||||||
|
let five = Some(5);
|
||||||
|
let six = plus_one(five);
|
||||||
|
let none = plus_one(None);
|
||||||
|
|
||||||
|
if let __ = six {
|
||||||
|
println!("{}", n);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
panic!("NEVER LET THIS RUN!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn plus_one(x: Option<i32>) -> Option<i32> {
|
||||||
|
match x {
|
||||||
|
__ => None,
|
||||||
|
__ => Some(i + 1),
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟🌟🌟 Implement a <code>linked-list</code> via enums.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
use crate::List::*;
|
||||||
|
|
||||||
|
enum List {
|
||||||
|
// Cons: Tuple struct that wraps an element and a pointer to the next node
|
||||||
|
Cons(u32, Box<List>),
|
||||||
|
// Nil: A node that signifies the end of the linked list
|
||||||
|
Nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods can be attached to an enum
|
||||||
|
impl List {
|
||||||
|
// Create an empty list
|
||||||
|
fn new() -> List {
|
||||||
|
// `Nil` has type `List`
|
||||||
|
Nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consume a list, and return the same list with a new element at its front
|
||||||
|
fn prepend(self, elem: u32) -> __ {
|
||||||
|
// `Cons` also has type List
|
||||||
|
Cons(elem, Box::new(self))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the length of the list
|
||||||
|
fn len(&self) -> u32 {
|
||||||
|
// `self` has to be matched, because the behavior of this method
|
||||||
|
// depends on the variant of `self`
|
||||||
|
// `self` has type `&List`, and `*self` has type `List`, matching on a
|
||||||
|
// concrete type `T` is preferred over a match on a reference `&T`
|
||||||
|
// After Rust 2018 you can use self here and tail (with no ref) below as well,
|
||||||
|
// rust will infer &s and ref tail.
|
||||||
|
// See https://doc.rust-lang.org/edition-guide/rust-2018/ownership-and-lifetimes/default-match-bindings.html
|
||||||
|
match *self {
|
||||||
|
// Can't take ownership of the tail, because `self` is borrowed;
|
||||||
|
// Instead take a reference to the tail
|
||||||
|
Cons(_, ref tail) => 1 + tail.len(),
|
||||||
|
// Base Case: An empty list has zero length
|
||||||
|
Nil => 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return representation of the list as a (heap allocated) string
|
||||||
|
fn stringify(&self) -> String {
|
||||||
|
match *self {
|
||||||
|
Cons(head, __ tail) => {
|
||||||
|
// `format!` is similar to `print!`, but returns a heap
|
||||||
|
// allocated string instead of printing to the console
|
||||||
|
format!("{}, {}", head, tail.__())
|
||||||
|
},
|
||||||
|
Nil => {
|
||||||
|
format!("Nil")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Create an empty linked list
|
||||||
|
let mut list = List::new();
|
||||||
|
|
||||||
|
// Prepend some elements
|
||||||
|
list = list.prepend(1);
|
||||||
|
list = list.prepend(2);
|
||||||
|
list = list.prepend(3);
|
||||||
|
|
||||||
|
// Show the final state of the list
|
||||||
|
println!("linked list has length: {}", list.len());
|
||||||
|
println!("{}", list.stringify());
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/enum.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../compound-types/struct.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="../flow-control.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="../compound-types/struct.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="../flow-control.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
229
compound-types/intro.html
Normal file
229
compound-types/intro.html
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Compound Types - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/compound-types/intro.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="compound-types"><a class="header" href="#compound-types">Compound Types</a></h1>
|
||||||
|
<p>Learning resources:</p>
|
||||||
|
<ul>
|
||||||
|
<li>English: <a href="https://doc.rust-lang.org/book/ch04-03-slices.html">Rust Book 4.3, 5.1, 6.1, 8.2</a></li>
|
||||||
|
<li>简体中文: <a href="https://course.rs/basic/compound-type/intro.html">Rust语言圣经 - 复合类型</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../ownership/borrowing.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="../compound-types/string.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="../ownership/borrowing.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="../compound-types/string.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
317
compound-types/slice.html
Normal file
317
compound-types/slice.html
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Slice - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/compound-types/slice.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="slice"><a class="header" href="#slice">Slice</a></h1>
|
||||||
|
<p>Slices are similar to arrays, but their length is not known at compile time, so you can't use slice directly.</p>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟 Here, both <code>[i32]</code> and <code>str</code> are slice types, but directly using it will cause errors. You have to use the reference of the slice instead: <code>&[i32]</code>, <code>&str</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the errors, DON'T add new lines!
|
||||||
|
fn main() {
|
||||||
|
let arr = [1, 2, 3];
|
||||||
|
let s1: [i32] = arr[0..2];
|
||||||
|
|
||||||
|
let s2: str = "hello, world" as str;
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>A slice reference is a two-word object, for simplicity reasons, from now on we will use slice instead of <code>slice reference</code>. The first word is a pointer to the data, and the second word is the length of the slice. The word size is the same as usize, determined by the processor architecture, e.g. 64 bits on an x86-64. Slices can be used to borrow a section of an array, and have the type signature <code>&[T]</code>.</p>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let arr: [char; 3] = ['中', '国', '人'];
|
||||||
|
|
||||||
|
let slice = &arr[..2];
|
||||||
|
|
||||||
|
// Modify '8' to make it work
|
||||||
|
// TIPS: slice( reference ) IS NOT an array, if it is an array, then `assert!` will be passed: Each of the two chars '中' and '国' occupies 4 bytes, 2 * 4 = 8
|
||||||
|
assert!(std::mem::size_of_val(&slice) == 8);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let arr: [i32; 5] = [1, 2, 3, 4, 5];
|
||||||
|
// Fill the blanks to make the code work
|
||||||
|
let slice: __ = __;
|
||||||
|
assert_eq!(slice, &[2, 3, 4]);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="string-slices"><a class="header" href="#string-slices">String slices</a></h3>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("hello");
|
||||||
|
|
||||||
|
let slice1 = &s[0..2];
|
||||||
|
// Fill the blank to make the code work, DON'T USE 0..2 again
|
||||||
|
let slice2 = &s[__];
|
||||||
|
|
||||||
|
assert_eq!(slice1, slice2);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let s = "你好,世界";
|
||||||
|
// Modify this line to make the code work
|
||||||
|
let slice = &s[0..2];
|
||||||
|
|
||||||
|
assert!(slice == "你");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟 <code>&String</code> can be implicitly converted into <code>&str</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix errors
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello world");
|
||||||
|
|
||||||
|
// Here, &s is `&String` type, but `first_letter` needs a `&str` type.
|
||||||
|
// It works because `&String` can be implicitly converted to `&str. If you want to know more, this is called `Deref coercion`.
|
||||||
|
let letter = first_letter(&s);
|
||||||
|
|
||||||
|
s.clear(); // error!
|
||||||
|
|
||||||
|
println!("the first letter is: {}", letter);
|
||||||
|
}
|
||||||
|
fn first_letter(s: &str) -> &str {
|
||||||
|
&s[..1]
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/slice.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../compound-types/array.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="../compound-types/tuple.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="../compound-types/array.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="../compound-types/tuple.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
459
compound-types/string.html
Normal file
459
compound-types/string.html
Normal file
@ -0,0 +1,459 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>string - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/compound-types/string.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="string"><a class="header" href="#string">String</a></h1>
|
||||||
|
<p>The type of string literal <code>"hello, world"</code> is <code>&str</code>, e.g <code>let s: &str = "hello, world"</code>.</p>
|
||||||
|
<h3 id="str-and-str"><a class="header" href="#str-and-str">Str and &str</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟 We can't use <code>str</code> type in normal ways, but we can use <code>&str</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix error without adding new line
|
||||||
|
fn main() {
|
||||||
|
let s: str = "hello, world";
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟 We can only use <code>str</code> by boxing it, <code>&</code> can be used to convert <code>Box<str></code> to <code>&str</code></li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the error with at least two solutions
|
||||||
|
fn main() {
|
||||||
|
let s: Box<str> = "hello, world".into();
|
||||||
|
greetings(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn greetings(s: &str) {
|
||||||
|
println!("{}",s)
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="string-1"><a class="header" href="#string-1">String</a></h3>
|
||||||
|
<p><code>String</code> type is defined in std and stored as a vector of bytes (Vec<u8>), but guaranteed to always be a valid UTF-8 sequence. String is heap allocated, growable and not null terminated.</p>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blank
|
||||||
|
fn main() {
|
||||||
|
let mut s = __;
|
||||||
|
s.push_str("hello, world");
|
||||||
|
s.push('!');
|
||||||
|
|
||||||
|
assert_eq!(s, "hello, world!");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix all errors without adding newline
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("hello");
|
||||||
|
s.push(',');
|
||||||
|
s.push(" world");
|
||||||
|
s += "!".to_string();
|
||||||
|
|
||||||
|
println!("{}", s);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟 <code>replace</code> can be used to replace substring</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blank
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("I like dogs");
|
||||||
|
// Allocate new memory and store the modified string there
|
||||||
|
let s1 = s.__("dogs", "cats");
|
||||||
|
|
||||||
|
assert_eq!(s1, "I like cats");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>More <code>String</code> methods can be found under <a href="https://doc.rust-lang.org/std/string/struct.String.html">String</a> module.</p>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟 You can only concat a <code>String</code> with <code>&str</code>, and <code>String</code>'s ownership can be moved to another variable.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix errors without removing any line
|
||||||
|
fn main() {
|
||||||
|
let s1 = String::from("hello,");
|
||||||
|
let s2 = String::from("world!");
|
||||||
|
let s3 = s1 + s2;
|
||||||
|
assert_eq!(s3, "hello,world!");
|
||||||
|
println!("{}", s1);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="str-and-string"><a class="header" href="#str-and-string">&str and String</a></h3>
|
||||||
|
<p>Opposite to the seldom using of <code>str</code>, <code>&str</code> and <code>String</code> are used everywhere!</p>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟 <code>&str</code> can be converted to <code>String</code> in two ways</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix error with at least two solutions
|
||||||
|
fn main() {
|
||||||
|
let s = "hello, world";
|
||||||
|
greetings(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn greetings(s: String) {
|
||||||
|
println!("{}", s)
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟 We can use <code>String::from</code> or <code>to_string</code> to convert a <code>&str</code> to <code>String</code></li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Use two approaches to fix the error and without adding a new line
|
||||||
|
fn main() {
|
||||||
|
let s = "hello, world".to_string();
|
||||||
|
let s1: &str = s;
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="string-escapes"><a class="header" href="#string-escapes">String escapes</a></h3>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
// You can use escapes to write bytes by their hexadecimal values
|
||||||
|
// Fill the blank below to show "I'm writing Rust"
|
||||||
|
let byte_escape = "I'm writing Ru\x73__!";
|
||||||
|
println!("What are you doing\x3F (\\x3F means ?) {}", byte_escape);
|
||||||
|
|
||||||
|
// ...Or Unicode code points.
|
||||||
|
let unicode_codepoint = "\u{211D}";
|
||||||
|
let character_name = "\"DOUBLE-STRUCK CAPITAL R\"";
|
||||||
|
|
||||||
|
println!("Unicode character {} (U+211D) is called {}",
|
||||||
|
unicode_codepoint, character_name );
|
||||||
|
|
||||||
|
let long_string = "String literals
|
||||||
|
can span multiple lines.
|
||||||
|
The linebreak and indentation here \
|
||||||
|
can be escaped too!";
|
||||||
|
println!("{}", long_string);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="10">
|
||||||
|
<li>🌟🌟🌟 Sometimes there are just too many characters that need to be escaped or it's just much more convenient to write a string out as-is. This is where raw string literals come into play.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
/* Fill in the blank and fix the errors */
|
||||||
|
fn main() {
|
||||||
|
let raw_str = r"Escapes don't work here: \x3F \u{211D}";
|
||||||
|
// Modify above line to make it work
|
||||||
|
assert_eq!(raw_str, "Escapes don't work here: ? ℝ");
|
||||||
|
|
||||||
|
// If you need quotes in a raw string, add a pair of #s
|
||||||
|
let quotes = r#"And then I said: "There is no escape!""#;
|
||||||
|
println!("{}", quotes);
|
||||||
|
|
||||||
|
// If you need "# in your string, just use more #s in the delimiter.
|
||||||
|
// You can use up to 65535 #s.
|
||||||
|
let delimiter = r###"A string with "# in it. And even "##!"###;
|
||||||
|
println!("{}", delimiter);
|
||||||
|
|
||||||
|
// Fill the blank
|
||||||
|
let long_delimiter = __;
|
||||||
|
assert_eq!(long_delimiter, "Hello, \"##\"");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="byte-string"><a class="header" href="#byte-string">Byte string</a></h3>
|
||||||
|
<p>Want a string that's not UTF-8? (Remember, str and String must be valid UTF-8). Or maybe you want an array of bytes that's mostly text? Byte strings to the rescue!</p>
|
||||||
|
<p><strong>Example</strong>:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::str;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Note that this is not actually a `&str`
|
||||||
|
let bytestring: &[u8; 21] = b"this is a byte string";
|
||||||
|
|
||||||
|
// Byte arrays don't have the `Display` trait, so printing them is a bit limited
|
||||||
|
println!("A byte string: {:?}", bytestring);
|
||||||
|
|
||||||
|
// Byte strings can have byte escapes...
|
||||||
|
let escaped = b"\x52\x75\x73\x74 as bytes";
|
||||||
|
// ...But no unicode escapes
|
||||||
|
// let escaped = b"\u{211D} Is not allowed";
|
||||||
|
println!("Some escaped bytes: {:?}", escaped);
|
||||||
|
|
||||||
|
|
||||||
|
// Raw byte strings work just like raw strings
|
||||||
|
let raw_bytestring = br"\u{211D} is not escaped here";
|
||||||
|
println!("{:?}", raw_bytestring);
|
||||||
|
|
||||||
|
// Converting a byte array to `str` can fail
|
||||||
|
if let Ok(my_str) = str::from_utf8(raw_bytestring) {
|
||||||
|
println!("And the same as text: '{}'", my_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
let _quotes = br#"You can also use "fancier" formatting, \
|
||||||
|
like with normal raw strings"#;
|
||||||
|
|
||||||
|
// Byte strings don't have to be UTF-8
|
||||||
|
let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82\xbb"; // "ようこそ" In SHIFT-JIS
|
||||||
|
|
||||||
|
// But then they can't always be converted to `str`
|
||||||
|
match str::from_utf8(shift_jis) {
|
||||||
|
Ok(my_str) => println!("Conversion successful: '{}'", my_str),
|
||||||
|
Err(e) => println!("Conversion failed: {:?}", e),
|
||||||
|
};
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>A more detailed listing of the ways to write string literals and escape characters is given in the <a href="https://doc.rust-lang.org/reference/tokens.html">'Tokens' chapter</a> of the Rust Reference.</p>
|
||||||
|
<h3 id="string-index"><a class="header" href="#string-index">String index</a></h3>
|
||||||
|
<ol start="11">
|
||||||
|
<li>🌟🌟🌟 You can't use index to access a char in a string, but you can use slice <code>&s1[start..end]</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let s1 = String::from("hi,中国");
|
||||||
|
let h = s1[0]; // Modify this line to fix the error, tips: `h` only takes 1 byte in UTF8 format
|
||||||
|
assert_eq!(h, "h");
|
||||||
|
|
||||||
|
let h1 = &s1[3..5]; // Modify this line to fix the error, tips: `中` takes 3 bytes in UTF8 format
|
||||||
|
assert_eq!(h1, "中");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="operate-on-utf8-string"><a class="header" href="#operate-on-utf8-string">Operate on UTF8 string</a></h3>
|
||||||
|
<ol start="12">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// Fill the blank to print each char in "你好,世界"
|
||||||
|
for c in "你好,世界".__ {
|
||||||
|
println!("{}", c)
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="utf8_slice"><a class="header" href="#utf8_slice">utf8_slice</a></h4>
|
||||||
|
<p>You can use <a href="https://docs.rs/utf8_slice/1.0.0/utf8_slice/fn.slice.html">utf8_slice</a> to slice UTF8 string, it can index chars instead of bytes.</p>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">use utf8_slice;
|
||||||
|
fn main() {
|
||||||
|
let s = "The 🚀 goes to the 🌑!";
|
||||||
|
|
||||||
|
let rocket = utf8_slice::slice(s, 4, 5);
|
||||||
|
// Will equal "🚀"
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/string.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../compound-types/intro.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="../compound-types/array.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="../compound-types/intro.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="../compound-types/array.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
436
compound-types/struct.html
Normal file
436
compound-types/struct.html
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Struct - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/compound-types/struct.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="struct"><a class="header" href="#struct">Struct</a></h1>
|
||||||
|
<h3 id="the-types-of-structs"><a class="header" href="#the-types-of-structs">The types of structs</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟 We must specify concrete values for each of the fields in struct.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the error
|
||||||
|
struct Person {
|
||||||
|
name: String,
|
||||||
|
age: u8,
|
||||||
|
hobby: String
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let age = 30;
|
||||||
|
let p = Person {
|
||||||
|
name: String::from("sunface"),
|
||||||
|
age,
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟 Unit struct don't have any fields. It can be useful when you need to implement a trait on some type but don’t have any data that you want to store in the type itself.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
struct Unit;
|
||||||
|
trait SomeTrait {
|
||||||
|
// ...Some behaviors defined here.
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't care about what fields are in the Unit, but we care about its behaviors.
|
||||||
|
// So we use a struct with no fields and implement some behaviors for it
|
||||||
|
impl SomeTrait for Unit { }
|
||||||
|
fn main() {
|
||||||
|
let u = Unit;
|
||||||
|
do_something_with_unit(u);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the blank to make the code work
|
||||||
|
fn do_something_with_unit(u: __) { }</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟🌟 Tuple struct looks similar to tuples, it has added meaning the struct name provides but has no named fields. It's useful when you want to give the whole tuple a name, but don't care about the fields's names.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the error and fill the blanks
|
||||||
|
struct Color(i32, i32, i32);
|
||||||
|
struct Point(i32, i32, i32);
|
||||||
|
fn main() {
|
||||||
|
let v = Point(__, __, __);
|
||||||
|
check_color(v);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_color(p: Color) {
|
||||||
|
let (x, _, _) = p;
|
||||||
|
assert_eq!(x, 0);
|
||||||
|
assert_eq!(p.1, 127);
|
||||||
|
assert_eq!(__, 255);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="operating-on-structs"><a class="header" href="#operating-on-structs">Operating on structs</a></h3>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟 You can make a whole struct mutable when instantiating it, but Rust doesn't allow us to mark only certain fields as mutable.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blank and fix the error without adding/removing new line
|
||||||
|
struct Person {
|
||||||
|
name: String,
|
||||||
|
age: u8,
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let age = 18;
|
||||||
|
let p = Person {
|
||||||
|
name: String::from("sunface"),
|
||||||
|
age,
|
||||||
|
};
|
||||||
|
|
||||||
|
// How can you believe sunface is only 18?
|
||||||
|
p.age = 30;
|
||||||
|
|
||||||
|
// Fill the blank
|
||||||
|
__ = String::from("sunfei");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟 Using <em>field init shorthand syntax</em> to reduce repetitions.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blank
|
||||||
|
struct Person {
|
||||||
|
name: String,
|
||||||
|
age: u8,
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_person(name: String, age: u8) -> Person {
|
||||||
|
Person {
|
||||||
|
age,
|
||||||
|
__
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟 You can create instance from other instance with <em>struct update syntax</em></li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blank to make the code work
|
||||||
|
struct User {
|
||||||
|
active: bool,
|
||||||
|
username: String,
|
||||||
|
email: String,
|
||||||
|
sign_in_count: u64,
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let u1 = User {
|
||||||
|
email: String::from("someone@example.com"),
|
||||||
|
username: String::from("sunface"),
|
||||||
|
active: true,
|
||||||
|
sign_in_count: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
let u2 = set_email(u1);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_email(u: User) -> User {
|
||||||
|
User {
|
||||||
|
email: String::from("contact@im.dev"),
|
||||||
|
__
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="print-the-structs"><a class="header" href="#print-the-structs">Print the structs</a></h3>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟 We can use <code>#[derive(Debug)]</code> to <a href="https://doc.rust-lang.org/book/ch05-02-example-structs.html?highlight=%23%5Bderive(Debug)%5D#adding-useful-functionality-with-derived-traits">make a struct printable</a>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill the blanks to make the code work
|
||||||
|
#[__]
|
||||||
|
struct Rectangle {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let scale = 2;
|
||||||
|
let rect1 = Rectangle {
|
||||||
|
width: dbg!(30 * scale), // Print debug info to stderr and assign the value of `30 * scale` to `width`
|
||||||
|
height: 50,
|
||||||
|
};
|
||||||
|
|
||||||
|
dbg!(&rect1); // Print debug info to stderr
|
||||||
|
|
||||||
|
println!(__, rect1); // Print debug info to stdout
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="partial-move"><a class="header" href="#partial-move">Partial move</a></h3>
|
||||||
|
<p>Within the destructuring of a single variable, both by-move and by-reference pattern bindings can be used at the same time. Doing this will result in a partial move of the variable, which means that parts of the variable will be moved while other parts stay. In such a case, the parent variable cannot be used afterwards as a whole, however the parts that are only referenced (and not moved) can still be used.</p>
|
||||||
|
<h4 id="example"><a class="header" href="#example">Example</a></h4>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Person {
|
||||||
|
name: String,
|
||||||
|
age: Box<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let person = Person {
|
||||||
|
name: String::from("Alice"),
|
||||||
|
age: Box::new(20),
|
||||||
|
};
|
||||||
|
|
||||||
|
// `name` is moved out of person, but `age` is referenced
|
||||||
|
let Person { name, ref age } = person;
|
||||||
|
|
||||||
|
println!("The person's age is {}", age);
|
||||||
|
|
||||||
|
println!("The person's name is {}", name);
|
||||||
|
|
||||||
|
// Error! borrow of partially moved value: `person` partial move occurs
|
||||||
|
//println!("The person struct is {:?}", person);
|
||||||
|
|
||||||
|
// `person` cannot be used but `person.age` can be used as it is not moved
|
||||||
|
println!("The person's age from person struct is {}", person.age);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="exercises"><a class="header" href="#exercises">Exercises</a></h4>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix errors to make it work
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct File {
|
||||||
|
name: String,
|
||||||
|
data: String,
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let f = File {
|
||||||
|
name: String::from("readme.md"),
|
||||||
|
data: "Rust By Practice".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
let _name = f.name;
|
||||||
|
|
||||||
|
// ONLY modify this line
|
||||||
|
println!("{}, {}, {:?}",f.name, f.data, f);
|
||||||
|
} </code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/struct.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../compound-types/tuple.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="../compound-types/enum.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="../compound-types/tuple.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="../compound-types/enum.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
308
compound-types/tuple.html
Normal file
308
compound-types/tuple.html
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Tuple - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/compound-types/tuple.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="tuple"><a class="header" href="#tuple">Tuple</a></h1>
|
||||||
|
<ol>
|
||||||
|
<li>🌟 Elements in a tuple can have different types. Tuple's type signature is <code>(T1, T2, ...)</code>, where <code>T1</code>, <code>T2</code> are the types of tuple's members.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let _t0: (u8,i16) = (0, -1);
|
||||||
|
// Tuples can be tuple's members
|
||||||
|
let _t1: (u8, (i16, u32)) = (0, (-1, 1));
|
||||||
|
// Fill the blanks to make the code work
|
||||||
|
let t: (u8, __, i64, __, __) = (1u8, 2u16, 3i64, "hello", String::from(", world"));
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟 Members can be extracted from the tuple using indexing.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Make it work
|
||||||
|
fn main() {
|
||||||
|
let t = ("i", "am", "sunface");
|
||||||
|
assert_eq!(t.1, "sunface");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟 Long tuples cannot be printed</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the error
|
||||||
|
fn main() {
|
||||||
|
let too_long_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
|
||||||
|
println!("too long tuple: {:?}", too_long_tuple);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟 Destructuring tuple with pattern.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let tup = (1, 6.4, "hello");
|
||||||
|
|
||||||
|
// Fill the blank to make the code work
|
||||||
|
let __ = tup;
|
||||||
|
|
||||||
|
assert_eq!(x, 1);
|
||||||
|
assert_eq!(y, "hello");
|
||||||
|
assert_eq!(z, 6.4);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟 Destructure assignments.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
let (x, y, z);
|
||||||
|
|
||||||
|
// Fill the blank
|
||||||
|
__ = (1, 2, 3);
|
||||||
|
|
||||||
|
assert_eq!(x, 3);
|
||||||
|
assert_eq!(y, 1);
|
||||||
|
assert_eq!(z, 2);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟 Tuples can be used as function arguments and return values</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// Fill the blank, need a few computations here.
|
||||||
|
let (x, y) = sum_multiply(__);
|
||||||
|
|
||||||
|
assert_eq!(x, 5);
|
||||||
|
assert_eq!(y, 6);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sum_multiply(nums: (i32, i32)) -> (i32, i32) {
|
||||||
|
(nums.0 + nums.1, nums.0 * nums.1)
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/compound-types/tuple.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../compound-types/slice.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="../compound-types/struct.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="../compound-types/slice.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="../compound-types/struct.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
320
crate-module/crate.html
Normal file
320
crate-module/crate.html
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Package and Crate - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/crate-module/crate.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="package-and-crate"><a class="header" href="#package-and-crate">Package and Crate</a></h1>
|
||||||
|
<p>A package is a project which you create with Cargo (in most cases), so it contains a <code>Cargo.toml</code> file in it.</p>
|
||||||
|
<ol>
|
||||||
|
<li>🌟 Create a package with below layout:</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="language-shell">.
|
||||||
|
├── Cargo.toml
|
||||||
|
└── src
|
||||||
|
└── main.rs
|
||||||
|
|
||||||
|
1 directory, 2 files
|
||||||
|
</code></pre>
|
||||||
|
<pre><code class="language-toml"># in Cargo.toml
|
||||||
|
[package]
|
||||||
|
name = "hello-package"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
</code></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>Note! We will use this package across the whole chapter as a practice project.</p>
|
||||||
|
</blockquote>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟 Create a package with below layout:</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="language-shell">.
|
||||||
|
├── Cargo.toml
|
||||||
|
└── src
|
||||||
|
└── lib.rs
|
||||||
|
|
||||||
|
1 directory, 2 files
|
||||||
|
</code></pre>
|
||||||
|
<pre><code class="language-toml"># in Cargo.toml
|
||||||
|
[package]
|
||||||
|
name = "hello-package1"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
</code></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>Note! This package could be safely removed due to the first one's existence.</p>
|
||||||
|
</blockquote>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* FILL in the blank with your ANSWER */
|
||||||
|
|
||||||
|
// Q: What's the difference between package number 1 and number 2?
|
||||||
|
// A: __</code></pre></pre>
|
||||||
|
<h2 id="crate"><a class="header" href="#crate">Crate</a></h2>
|
||||||
|
<p>A crate is a binary or library. The crate root is a source file that the Rust compiler starts from and makes up the root module of the crate.</p>
|
||||||
|
<p>In package <code>hello-package</code>, there is binary crate with the same name as the package : <code>hello-package</code>, and <code>src/main.rs</code> is the crate root of this binary crate.</p>
|
||||||
|
<p>Similar to <code>hello-package</code>, <code>hello-package1</code> also has a crate in it, however, this package doesn't contain a binary crate but a library crate, and <code>src/lib.rs</code> is the crate root.</p>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* FILL in the blank with your ANSWER */
|
||||||
|
|
||||||
|
// Q: What's the name of the library crate in package `hello-package1`?
|
||||||
|
// A: __</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟 Add a library crate for <code>hello-package</code> and describe it's files tree below:</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="language-shell editable"># FILL in the blanks
|
||||||
|
.
|
||||||
|
├── Cargo.lock
|
||||||
|
├── Cargo.toml
|
||||||
|
├── src
|
||||||
|
│ ├── __
|
||||||
|
│ └── __
|
||||||
|
</code></pre>
|
||||||
|
<p>After this step, there should be two crates in package <code>hello-package</code>: <strong>a binary crate and a library crate, both with the same name as the package</strong>.</p>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟🌟 A package can contain at most one library crate, but it can contain as many binary crates as you would like by placing files in <code>src/bin</code> directory: <strong>each file will be a separate binary crate with the same name as the file</strong>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="language-shell editable"># Create a package which contains
|
||||||
|
# 1. three binary crates: `hello-package`, `main1` and `main2`
|
||||||
|
# 2. one library crate
|
||||||
|
# describe the directory tree below
|
||||||
|
.
|
||||||
|
├── Cargo.toml
|
||||||
|
├── Cargo.lock
|
||||||
|
├── src
|
||||||
|
│ ├── __
|
||||||
|
│ ├── __
|
||||||
|
│ └── __
|
||||||
|
│ └── __
|
||||||
|
│ └── __
|
||||||
|
├── tests # directory for integrated tests files
|
||||||
|
│ └── some_integration_tests.rs
|
||||||
|
├── benches # dir for benchmark files
|
||||||
|
│ └── simple_bench.rs
|
||||||
|
└── examples # dir for example files
|
||||||
|
└── simple_example.rs
|
||||||
|
</code></pre>
|
||||||
|
<p>Yep, as you can see, the above package structure is very standard and is widely used in many Rust projects.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/crate-module/crate.md">here</a> (under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../crate-module/intro.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="../crate-module/module.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="../crate-module/intro.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="../crate-module/module.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
229
crate-module/intro.html
Normal file
229
crate-module/intro.html
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Crate and Module - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/crate-module/intro.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="crate-and-module"><a class="header" href="#crate-and-module">Crate and module</a></h1>
|
||||||
|
<p>Learning resources:</p>
|
||||||
|
<ul>
|
||||||
|
<li>English: <a href="https://doc.rust-lang.org/book/ch07-00-managing-growing-projects-with-packages-crates-and-modules.html">Rust Book Chapter 7</a></li>
|
||||||
|
<li>简体中文: <a href="https://course.rs/basic/crate-module/intro.html">Rust语言圣经 - 包和模块</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../result-panic/result.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="../crate-module/crate.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="../result-panic/result.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="../crate-module/crate.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
383
crate-module/module.html
Normal file
383
crate-module/module.html
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Module - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/crate-module/module.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="module"><a class="header" href="#module">Module</a></h1>
|
||||||
|
<p>Modules let us organize the code within a crate into groups for readability and ease of reuse. Module also controls the privacy of items, which is whether an item can be seen by outside code( public ), or is just an internal implementation and not available for outside code( private ).</p>
|
||||||
|
<p>We have created a package named <code>hello-package</code> in previous chapter, and it looks like this:</p>
|
||||||
|
<pre><code class="language-shell">.
|
||||||
|
├── Cargo.toml
|
||||||
|
├── src
|
||||||
|
│ ├── lib.rs
|
||||||
|
│ └── main.rs
|
||||||
|
</code></pre>
|
||||||
|
<p>Now it's time to create some modules in the library crate and use them in the binary crate, let's start.</p>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟 Implement module <code>front_of_house</code> based on the module tree below:</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="language-shell">library crate root
|
||||||
|
└── front_of_house
|
||||||
|
├── hosting
|
||||||
|
│ ├── add_to_waitlist
|
||||||
|
│ └── seat_at_table
|
||||||
|
└── serving
|
||||||
|
├── take_order
|
||||||
|
├── serve_order
|
||||||
|
├── take_payment
|
||||||
|
└── complain
|
||||||
|
</code></pre>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// FILL in the blank
|
||||||
|
// in __.rs
|
||||||
|
|
||||||
|
mod front_of_house {
|
||||||
|
// IMPLEMENT this module..
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟 Let's call <code>add_to_waitlist</code> from a function <code>eat_at_restaurant</code> which is within the library crate root.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// In lib.rs
|
||||||
|
|
||||||
|
// FILL in the blanks and FIX the errors
|
||||||
|
// You need to make something public with `pub` to provide accessibility for outside code `fn eat_at_restaurant()`
|
||||||
|
mod front_of_house {
|
||||||
|
/* ...snip... */
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eat_at_restaurant() {
|
||||||
|
// Call add_to_waitlist with **absolute path**:
|
||||||
|
__::add_to_waitlist();
|
||||||
|
|
||||||
|
// Call with **relative path**
|
||||||
|
__::add_to_waitlist();
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟 You can use <code>super</code> to import items within the parent module</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// In lib.rs
|
||||||
|
|
||||||
|
mod back_of_house {
|
||||||
|
fn fix_incorrect_order() {
|
||||||
|
cook_order();
|
||||||
|
// FILL in the blank in three ways
|
||||||
|
//1. using keyword `super`
|
||||||
|
//2. using absolute path
|
||||||
|
__::serve_order();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cook_order() {}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="separating-modules-into-different-files"><a class="header" href="#separating-modules-into-different-files">Separating modules into different files</a></h3>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// In lib.rs
|
||||||
|
pub mod front_of_house {
|
||||||
|
pub mod hosting {
|
||||||
|
pub fn add_to_waitlist() {}
|
||||||
|
|
||||||
|
pub fn seat_at_table() -> String {
|
||||||
|
String::from("sit down please")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod serving {
|
||||||
|
pub fn take_order() {}
|
||||||
|
|
||||||
|
pub fn serve_order() {}
|
||||||
|
|
||||||
|
pub fn take_payment() {}
|
||||||
|
|
||||||
|
// Maybe you don't want the guest hearing the your complaining about them
|
||||||
|
// So just make it private
|
||||||
|
fn complain() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eat_at_restaurant() -> String {
|
||||||
|
front_of_house::hosting::add_to_waitlist();
|
||||||
|
|
||||||
|
back_of_house::cook_order();
|
||||||
|
|
||||||
|
String::from("yummy yummy!")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod back_of_house {
|
||||||
|
pub fn fix_incorrect_order() {
|
||||||
|
cook_order();
|
||||||
|
crate::front_of_house::serving::serve_order();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cook_order() {}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟🌟🌟 Please separate the modules and codes above into files resident in below dir tree :</li>
|
||||||
|
</ol>
|
||||||
|
<pre><code class="language-shell">.
|
||||||
|
├── Cargo.toml
|
||||||
|
├── src
|
||||||
|
│ ├── back_of_house.rs
|
||||||
|
│ ├── front_of_house
|
||||||
|
│ │ ├── hosting.rs
|
||||||
|
│ │ ├── mod.rs
|
||||||
|
│ │ └── serving.rs
|
||||||
|
│ ├── lib.rs
|
||||||
|
│ └── main.rs
|
||||||
|
</code></pre>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// In src/lib.rs
|
||||||
|
|
||||||
|
// IMPLEMENT...</code></pre></pre>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// In src/back_of_house.rs
|
||||||
|
|
||||||
|
// IMPLEMENT...</code></pre></pre>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// In src/front_of_house/mod.rs
|
||||||
|
|
||||||
|
// IMPLEMENT...</code></pre></pre>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// In src/front_of_house/hosting.rs
|
||||||
|
|
||||||
|
// IMPLEMENT...</code></pre></pre>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// In src/front_of_house/serving.rs
|
||||||
|
|
||||||
|
// IMPLEMENT...</code></pre></pre>
|
||||||
|
<h3 id="accessing-code-in-library-crate-from-binary-crate"><a class="header" href="#accessing-code-in-library-crate-from-binary-crate">Accessing code in library crate from binary crate</a></h3>
|
||||||
|
<p><strong>Please ensure you have completed the 4th exercise before making further progress.</strong></p>
|
||||||
|
<p>You should have below structures and the corresponding codes in them when reaching here:</p>
|
||||||
|
<pre><code class="language-shell">.
|
||||||
|
├── Cargo.toml
|
||||||
|
├── src
|
||||||
|
│ ├── back_of_house.rs
|
||||||
|
│ ├── front_of_house
|
||||||
|
│ │ ├── hosting.rs
|
||||||
|
│ │ ├── mod.rs
|
||||||
|
│ │ └── serving.rs
|
||||||
|
│ ├── lib.rs
|
||||||
|
│ └── main.rs
|
||||||
|
</code></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟🌟 Now we will call a few library functions from the binary crate.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// In src/main.rs
|
||||||
|
|
||||||
|
// FILL in the blank and FIX the errors
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(__, "sit down please");
|
||||||
|
assert_eq!(__,"yummy yummy!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/crate-module/module.md">here</a> (under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../crate-module/crate.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="../crate-module/use-pub.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="../crate-module/crate.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="../crate-module/use-pub.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
282
crate-module/use-pub.html
Normal file
282
crate-module/use-pub.html
Normal file
@ -0,0 +1,282 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Advanced use and pub - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/crate-module/use-pub.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="use-and-pub"><a class="header" href="#use-and-pub">Use and pub</a></h1>
|
||||||
|
<ol>
|
||||||
|
<li>🌟 We can bring two types of the same name into the same scope with use, but you need <code>as</code> keyword.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::fmt::Result;
|
||||||
|
use std::io::Result;
|
||||||
|
|
||||||
|
fn main() {}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟 If we are using multiple items defined in the same crate or module, then listing each item on its own line will take up too much vertical space.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blank in two ways
|
||||||
|
// DON'T add new code line
|
||||||
|
use std::collections::__;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _c1:HashMap<&str, i32> = HashMap::new();
|
||||||
|
let mut c2 = BTreeMap::new();
|
||||||
|
c2.insert(1, "a");
|
||||||
|
let _c3: HashSet<i32> = HashSet::new();
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="re-exporting-names-with-pub-use"><a class="header" href="#re-exporting-names-with-pub-use">Re-exporting names with <code>pub use</code></a></h3>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟🌟 In our recently created package <code>hello-package</code>, add something to make the below code work</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
assert_eq!(hello_package::hosting::seat_at_table(), "sit down please");
|
||||||
|
assert_eq!(hello_package::eat_at_restaurant(),"yummy yummy!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="pubin-crate"><a class="header" href="#pubin-crate">Pub(in Crate)</a></h3>
|
||||||
|
<p>Sometimes we want an item only be public to a certain crate. For this we can use the <code>pub(in Crate)</code> syntax.</p>
|
||||||
|
<h4 id="example"><a class="header" href="#example">Example</a></h4>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">pub mod a {
|
||||||
|
pub const I: i32 = 3;
|
||||||
|
|
||||||
|
fn semisecret(x: i32) -> i32 {
|
||||||
|
use self::b::c::J;
|
||||||
|
x + J
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bar(z: i32) -> i32 {
|
||||||
|
semisecret(I) * z
|
||||||
|
}
|
||||||
|
pub fn foo(y: i32) -> i32 {
|
||||||
|
semisecret(I) + y
|
||||||
|
}
|
||||||
|
|
||||||
|
mod b {
|
||||||
|
pub(in crate::a) mod c {
|
||||||
|
pub(in crate::a) const J: i32 = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="full-code"><a class="header" href="#full-code">Full Code</a></h3>
|
||||||
|
<p>The full code of <code>hello-package</code> is <a href="https://github.com/sunface/rust-by-practice/tree/master/practices/hello-package">here</a>.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/crate-module/use-pub.md">here</a> (under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../crate-module/module.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="../comments-docs.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="../crate-module/module.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="../comments-docs.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
643
css/chrome.css
Normal file
643
css/chrome.css
Normal file
@ -0,0 +1,643 @@
|
|||||||
|
/* CSS for UI elements (a.k.a. chrome) */
|
||||||
|
|
||||||
|
html {
|
||||||
|
scrollbar-color: var(--scrollbar) var(--bg);
|
||||||
|
}
|
||||||
|
#searchresults a,
|
||||||
|
.content a:link,
|
||||||
|
a:visited,
|
||||||
|
a > .hljs {
|
||||||
|
color: var(--links);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
body-container is necessary because mobile browsers don't seem to like
|
||||||
|
overflow-x on the body tag when there is a <meta name="viewport"> tag.
|
||||||
|
*/
|
||||||
|
#body-container {
|
||||||
|
/*
|
||||||
|
This is used when the sidebar pushes the body content off the side of
|
||||||
|
the screen on small screens. Without it, dragging on mobile Safari
|
||||||
|
will want to reposition the viewport in a weird way.
|
||||||
|
*/
|
||||||
|
overflow-x: clip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Menu Bar */
|
||||||
|
|
||||||
|
#menu-bar,
|
||||||
|
#menu-bar-hover-placeholder {
|
||||||
|
z-index: 101;
|
||||||
|
margin: auto calc(0px - var(--page-padding));
|
||||||
|
}
|
||||||
|
#menu-bar {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
background-color: var(--bg);
|
||||||
|
border-block-end-color: var(--bg);
|
||||||
|
border-block-end-width: 1px;
|
||||||
|
border-block-end-style: solid;
|
||||||
|
}
|
||||||
|
#menu-bar.sticky,
|
||||||
|
#menu-bar-hover-placeholder:hover + #menu-bar,
|
||||||
|
#menu-bar:hover,
|
||||||
|
html.sidebar-visible #menu-bar {
|
||||||
|
position: -webkit-sticky;
|
||||||
|
position: sticky;
|
||||||
|
top: 0 !important;
|
||||||
|
}
|
||||||
|
#menu-bar-hover-placeholder {
|
||||||
|
position: sticky;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
top: 0;
|
||||||
|
height: var(--menu-bar-height);
|
||||||
|
}
|
||||||
|
#menu-bar.bordered {
|
||||||
|
border-block-end-color: var(--table-border-color);
|
||||||
|
}
|
||||||
|
#menu-bar i, #menu-bar .icon-button {
|
||||||
|
position: relative;
|
||||||
|
padding: 0 8px;
|
||||||
|
z-index: 10;
|
||||||
|
line-height: var(--menu-bar-height);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.5s;
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 420px) {
|
||||||
|
#menu-bar i, #menu-bar .icon-button {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-button {
|
||||||
|
border: none;
|
||||||
|
background: none;
|
||||||
|
padding: 0;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
.icon-button i {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-buttons {
|
||||||
|
margin: 0 15px;
|
||||||
|
}
|
||||||
|
.right-buttons a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-buttons {
|
||||||
|
display: flex;
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
html:not(.js) .left-buttons button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-title {
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: 200;
|
||||||
|
font-size: 2.4rem;
|
||||||
|
line-height: var(--menu-bar-height);
|
||||||
|
text-align: center;
|
||||||
|
margin: 0;
|
||||||
|
flex: 1;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.menu-title {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-bar,
|
||||||
|
.menu-bar:visited,
|
||||||
|
.nav-chapters,
|
||||||
|
.nav-chapters:visited,
|
||||||
|
.mobile-nav-chapters,
|
||||||
|
.mobile-nav-chapters:visited,
|
||||||
|
.menu-bar .icon-button,
|
||||||
|
.menu-bar a i {
|
||||||
|
color: var(--icons);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-bar i:hover,
|
||||||
|
.menu-bar .icon-button:hover,
|
||||||
|
.nav-chapters:hover,
|
||||||
|
.mobile-nav-chapters i:hover {
|
||||||
|
color: var(--icons-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nav Icons */
|
||||||
|
|
||||||
|
.nav-chapters {
|
||||||
|
font-size: 2.5em;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: 0;
|
||||||
|
max-width: 150px;
|
||||||
|
min-width: 90px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
transition: color 0.5s, background-color 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-chapters:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: var(--theme-hover);
|
||||||
|
transition: background-color 0.15s, color 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-wrapper {
|
||||||
|
margin-block-start: 50px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mobile-nav-chapters {
|
||||||
|
font-size: 2.5em;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
width: 90px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: var(--sidebar-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only Firefox supports flow-relative values */
|
||||||
|
.previous { float: left; }
|
||||||
|
[dir=rtl] .previous { float: right; }
|
||||||
|
|
||||||
|
/* Only Firefox supports flow-relative values */
|
||||||
|
.next {
|
||||||
|
float: right;
|
||||||
|
right: var(--page-padding);
|
||||||
|
}
|
||||||
|
[dir=rtl] .next {
|
||||||
|
float: left;
|
||||||
|
right: unset;
|
||||||
|
left: var(--page-padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Use the correct buttons for RTL layouts*/
|
||||||
|
[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";}
|
||||||
|
[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; }
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1080px) {
|
||||||
|
.nav-wide-wrapper { display: none; }
|
||||||
|
.nav-wrapper { display: block; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sidebar-visible */
|
||||||
|
@media only screen and (max-width: 1380px) {
|
||||||
|
#sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper { display: none; }
|
||||||
|
#sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper { display: block; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inline code */
|
||||||
|
|
||||||
|
:not(pre) > .hljs {
|
||||||
|
display: inline;
|
||||||
|
padding: 0.1em 0.3em;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:not(pre):not(a) > .hljs {
|
||||||
|
color: var(--inline-code-color);
|
||||||
|
overflow-x: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover > .hljs {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
pre > .buttons {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 100;
|
||||||
|
right: 0px;
|
||||||
|
top: 2px;
|
||||||
|
margin: 0px;
|
||||||
|
padding: 2px 0px;
|
||||||
|
|
||||||
|
color: var(--sidebar-fg);
|
||||||
|
cursor: pointer;
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transition: visibility 0.1s linear, opacity 0.1s linear;
|
||||||
|
}
|
||||||
|
pre:hover > .buttons {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
pre > .buttons :hover {
|
||||||
|
color: var(--sidebar-active);
|
||||||
|
border-color: var(--icons-hover);
|
||||||
|
background-color: var(--theme-hover);
|
||||||
|
}
|
||||||
|
pre > .buttons i {
|
||||||
|
margin-inline-start: 8px;
|
||||||
|
}
|
||||||
|
pre > .buttons button {
|
||||||
|
cursor: inherit;
|
||||||
|
margin: 0px 5px;
|
||||||
|
padding: 4px 4px 3px 5px;
|
||||||
|
font-size: 23px;
|
||||||
|
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border-color: var(--icons);
|
||||||
|
background-color: var(--theme-popup-bg);
|
||||||
|
transition: 100ms;
|
||||||
|
transition-property: color,border-color,background-color;
|
||||||
|
color: var(--icons);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre > .buttons button.clip-button {
|
||||||
|
padding: 2px 4px 0px 6px;
|
||||||
|
}
|
||||||
|
pre > .buttons button.clip-button::before {
|
||||||
|
/* clipboard image from octicons (https://github.com/primer/octicons/tree/v2.0.0) MIT license
|
||||||
|
*/
|
||||||
|
content: url('data:image/svg+xml,<svg width="21" height="20" viewBox="0 0 24 25" \
|
||||||
|
xmlns="http://www.w3.org/2000/svg" aria-label="Copy to clipboard">\
|
||||||
|
<path d="M18 20h2v3c0 1-1 2-2 2H2c-.998 0-2-1-2-2V5c0-.911.755-1.667 1.667-1.667h5A3.323 3.323 0 \
|
||||||
|
0110 0a3.323 3.323 0 013.333 3.333h5C19.245 3.333 20 4.09 20 5v8.333h-2V9H2v14h16v-3zM3 \
|
||||||
|
7h14c0-.911-.793-1.667-1.75-1.667H13.5c-.957 0-1.75-.755-1.75-1.666C11.75 2.755 10.957 2 10 \
|
||||||
|
2s-1.75.755-1.75 1.667c0 .911-.793 1.666-1.75 1.666H4.75C3.793 5.333 3 6.09 3 7z"/>\
|
||||||
|
<path d="M4 19h6v2H4zM12 11H4v2h8zM4 17h4v-2H4zM15 15v-3l-4.5 4.5L15 21v-3l8.027-.032L23 15z"/>\
|
||||||
|
</svg>');
|
||||||
|
filter: var(--copy-button-filter);
|
||||||
|
}
|
||||||
|
pre > .buttons button.clip-button:hover::before {
|
||||||
|
filter: var(--copy-button-filter-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (pointer: coarse) {
|
||||||
|
pre > .buttons button {
|
||||||
|
/* On mobile, make it easier to tap buttons. */
|
||||||
|
padding: 0.3rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-resize-indicator {
|
||||||
|
/* Hide resize indicator on devices with limited accuracy */
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pre > code {
|
||||||
|
display: block;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: ACE editors overlap their buttons because ACE does absolute
|
||||||
|
positioning within the code block which breaks padding. The only solution I
|
||||||
|
can think of is to move the padding to the outer pre tag (or insert a div
|
||||||
|
wrapper), but that would require fixing a whole bunch of CSS rules.
|
||||||
|
*/
|
||||||
|
.hljs.ace_editor {
|
||||||
|
padding: 0rem 0rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre > .result {
|
||||||
|
margin-block-start: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search */
|
||||||
|
|
||||||
|
#searchresults a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
border-radius: 2px;
|
||||||
|
padding-block-start: 0;
|
||||||
|
padding-block-end: 1px;
|
||||||
|
padding-inline-start: 3px;
|
||||||
|
padding-inline-end: 3px;
|
||||||
|
margin-block-start: 0;
|
||||||
|
margin-block-end: -1px;
|
||||||
|
margin-inline-start: -3px;
|
||||||
|
margin-inline-end: -3px;
|
||||||
|
background-color: var(--search-mark-bg);
|
||||||
|
transition: background-color 300ms linear;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
mark.fade-out {
|
||||||
|
background-color: rgba(0,0,0,0) !important;
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchbar-outer {
|
||||||
|
margin-inline-start: auto;
|
||||||
|
margin-inline-end: auto;
|
||||||
|
max-width: var(--content-max-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
#searchbar {
|
||||||
|
width: 100%;
|
||||||
|
margin-block-start: 5px;
|
||||||
|
margin-block-end: 0;
|
||||||
|
margin-inline-start: auto;
|
||||||
|
margin-inline-end: auto;
|
||||||
|
padding: 10px 16px;
|
||||||
|
transition: box-shadow 300ms ease-in-out;
|
||||||
|
border: 1px solid var(--searchbar-border-color);
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: var(--searchbar-bg);
|
||||||
|
color: var(--searchbar-fg);
|
||||||
|
}
|
||||||
|
#searchbar:focus,
|
||||||
|
#searchbar.active {
|
||||||
|
box-shadow: 0 0 3px var(--searchbar-shadow-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchresults-header {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1em;
|
||||||
|
padding-block-start: 18px;
|
||||||
|
padding-block-end: 0;
|
||||||
|
padding-inline-start: 5px;
|
||||||
|
padding-inline-end: 0;
|
||||||
|
color: var(--searchresults-header-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchresults-outer {
|
||||||
|
margin-inline-start: auto;
|
||||||
|
margin-inline-end: auto;
|
||||||
|
max-width: var(--content-max-width);
|
||||||
|
border-block-end: 1px dashed var(--searchresults-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul#searchresults {
|
||||||
|
list-style: none;
|
||||||
|
padding-inline-start: 20px;
|
||||||
|
}
|
||||||
|
ul#searchresults li {
|
||||||
|
margin: 10px 0px;
|
||||||
|
padding: 2px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
ul#searchresults li.focus {
|
||||||
|
background-color: var(--searchresults-li-bg);
|
||||||
|
}
|
||||||
|
ul#searchresults span.teaser {
|
||||||
|
display: block;
|
||||||
|
clear: both;
|
||||||
|
margin-block-start: 5px;
|
||||||
|
margin-block-end: 0;
|
||||||
|
margin-inline-start: 20px;
|
||||||
|
margin-inline-end: 0;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
ul#searchresults span.teaser em {
|
||||||
|
font-weight: bold;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Sidebar */
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: var(--sidebar-width);
|
||||||
|
font-size: 0.875em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
overscroll-behavior-y: contain;
|
||||||
|
background-color: var(--sidebar-bg);
|
||||||
|
color: var(--sidebar-fg);
|
||||||
|
}
|
||||||
|
.sidebar-iframe-inner {
|
||||||
|
--padding: 10px;
|
||||||
|
|
||||||
|
background-color: var(--sidebar-bg);
|
||||||
|
padding: var(--padding);
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.4rem;
|
||||||
|
color: var(--sidebar-fg);
|
||||||
|
min-height: calc(100vh - var(--padding) * 2);
|
||||||
|
}
|
||||||
|
.sidebar-iframe-outer {
|
||||||
|
border: none;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
[dir=rtl] .sidebar { left: unset; right: 0; }
|
||||||
|
.sidebar-resizing {
|
||||||
|
-moz-user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
html:not(.sidebar-resizing) .sidebar {
|
||||||
|
transition: transform 0.3s; /* Animation: slide away */
|
||||||
|
}
|
||||||
|
.sidebar code {
|
||||||
|
line-height: 2em;
|
||||||
|
}
|
||||||
|
.sidebar .sidebar-scrollbox {
|
||||||
|
overflow-y: auto;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 10px 10px;
|
||||||
|
}
|
||||||
|
.sidebar .sidebar-resize-handle {
|
||||||
|
position: absolute;
|
||||||
|
cursor: col-resize;
|
||||||
|
width: 0;
|
||||||
|
right: calc(var(--sidebar-resize-indicator-width) * -1);
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-resize-handle .sidebar-resize-indicator {
|
||||||
|
width: 100%;
|
||||||
|
height: 12px;
|
||||||
|
background-color: var(--icons);
|
||||||
|
margin-inline-start: var(--sidebar-resize-indicator-space);
|
||||||
|
}
|
||||||
|
|
||||||
|
[dir=rtl] .sidebar .sidebar-resize-handle {
|
||||||
|
left: calc(var(--sidebar-resize-indicator-width) * -1);
|
||||||
|
right: unset;
|
||||||
|
}
|
||||||
|
.js .sidebar .sidebar-resize-handle {
|
||||||
|
cursor: col-resize;
|
||||||
|
width: calc(var(--sidebar-resize-indicator-width) - var(--sidebar-resize-indicator-space));
|
||||||
|
}
|
||||||
|
/* sidebar-hidden */
|
||||||
|
#sidebar-toggle-anchor:not(:checked) ~ .sidebar {
|
||||||
|
transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width)));
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
[dir=rtl] #sidebar-toggle-anchor:not(:checked) ~ .sidebar {
|
||||||
|
transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)));
|
||||||
|
}
|
||||||
|
.sidebar::-webkit-scrollbar {
|
||||||
|
background: var(--sidebar-bg);
|
||||||
|
}
|
||||||
|
.sidebar::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--scrollbar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sidebar-visible */
|
||||||
|
#sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||||
|
transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)));
|
||||||
|
}
|
||||||
|
[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||||
|
transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width)));
|
||||||
|
}
|
||||||
|
@media only screen and (min-width: 620px) {
|
||||||
|
#sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||||
|
transform: none;
|
||||||
|
margin-inline-start: calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width));
|
||||||
|
}
|
||||||
|
[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter {
|
||||||
|
list-style: none outside none;
|
||||||
|
padding-inline-start: 0;
|
||||||
|
line-height: 2.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter ol {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter li {
|
||||||
|
display: flex;
|
||||||
|
color: var(--sidebar-non-existant);
|
||||||
|
}
|
||||||
|
.chapter li a {
|
||||||
|
display: block;
|
||||||
|
padding: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--sidebar-fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter li a:hover {
|
||||||
|
color: var(--sidebar-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter li a.active {
|
||||||
|
color: var(--sidebar-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter li > a.toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
display: block;
|
||||||
|
margin-inline-start: auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
user-select: none;
|
||||||
|
opacity: 0.68;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter li > a.toggle div {
|
||||||
|
transition: transform 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* collapse the section */
|
||||||
|
.chapter li:not(.expanded) + li > ol {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter li.chapter-item {
|
||||||
|
line-height: 1.5em;
|
||||||
|
margin-block-start: 0.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter li.expanded > a.toggle div {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
width: 100%;
|
||||||
|
height: 3px;
|
||||||
|
margin: 5px 0px;
|
||||||
|
}
|
||||||
|
.chapter .spacer {
|
||||||
|
background-color: var(--sidebar-spacer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (-moz-touch-enabled: 1), (pointer: coarse) {
|
||||||
|
.chapter li a { padding: 5px 0; }
|
||||||
|
.spacer { margin: 10px 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
list-style: none outside none;
|
||||||
|
padding-inline-start: 20px;
|
||||||
|
line-height: 1.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Theme Menu Popup */
|
||||||
|
|
||||||
|
.theme-popup {
|
||||||
|
position: absolute;
|
||||||
|
left: 10px;
|
||||||
|
top: var(--menu-bar-height);
|
||||||
|
z-index: 1000;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 0.7em;
|
||||||
|
color: var(--fg);
|
||||||
|
background: var(--theme-popup-bg);
|
||||||
|
border: 1px solid var(--theme-popup-border);
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
display: none;
|
||||||
|
/* Don't let the children's background extend past the rounded corners. */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
[dir=rtl] .theme-popup { left: unset; right: 10px; }
|
||||||
|
.theme-popup .default {
|
||||||
|
color: var(--icons);
|
||||||
|
}
|
||||||
|
.theme-popup .theme {
|
||||||
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 2px 20px;
|
||||||
|
line-height: 25px;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: start;
|
||||||
|
cursor: pointer;
|
||||||
|
color: inherit;
|
||||||
|
background: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
.theme-popup .theme:hover {
|
||||||
|
background-color: var(--theme-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-selected::before {
|
||||||
|
display: inline-block;
|
||||||
|
content: "✓";
|
||||||
|
margin-inline-start: -14px;
|
||||||
|
width: 14px;
|
||||||
|
}
|
279
css/general.css
Normal file
279
css/general.css
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
/* Base styles and content styles */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
/* Browser default font-size is 16px, this way 1 rem = 10px */
|
||||||
|
font-size: 62.5%;
|
||||||
|
color-scheme: var(--color-scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-family: "Open Sans", sans-serif;
|
||||||
|
color: var(--fg);
|
||||||
|
background-color: var(--bg);
|
||||||
|
text-size-adjust: none;
|
||||||
|
-webkit-text-size-adjust: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.6rem;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-family: var(--mono-font) !important;
|
||||||
|
font-size: var(--code-font-size);
|
||||||
|
direction: ltr !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make long words/inline code not x overflow */
|
||||||
|
main {
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make wide tables scroll if they overflow */
|
||||||
|
.table-wrapper {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't change font size in headers. */
|
||||||
|
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
||||||
|
font-size: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left { float: left; }
|
||||||
|
.right { float: right; }
|
||||||
|
.boring { opacity: 0.6; }
|
||||||
|
.hide-boring .boring { display: none; }
|
||||||
|
.hidden { display: none !important; }
|
||||||
|
|
||||||
|
h2, h3 { margin-block-start: 2.5em; }
|
||||||
|
h4, h5 { margin-block-start: 2em; }
|
||||||
|
|
||||||
|
.header + .header h3,
|
||||||
|
.header + .header h4,
|
||||||
|
.header + .header h5 {
|
||||||
|
margin-block-start: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1:target::before,
|
||||||
|
h2:target::before,
|
||||||
|
h3:target::before,
|
||||||
|
h4:target::before,
|
||||||
|
h5:target::before,
|
||||||
|
h6:target::before {
|
||||||
|
display: inline-block;
|
||||||
|
content: "»";
|
||||||
|
margin-inline-start: -30px;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is broken on Safari as of version 14, but is fixed
|
||||||
|
in Safari Technology Preview 117 which I think will be Safari 14.2.
|
||||||
|
https://bugs.webkit.org/show_bug.cgi?id=218076
|
||||||
|
*/
|
||||||
|
:target {
|
||||||
|
/* Safari does not support logical properties */
|
||||||
|
scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
outline: 0;
|
||||||
|
padding: 0 var(--page-padding);
|
||||||
|
margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
|
||||||
|
}
|
||||||
|
.page-wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: var(--bg);
|
||||||
|
}
|
||||||
|
.no-js .page-wrapper,
|
||||||
|
.js:not(.sidebar-resizing) .page-wrapper {
|
||||||
|
transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
|
||||||
|
}
|
||||||
|
[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper {
|
||||||
|
transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0 5px 50px 5px;
|
||||||
|
}
|
||||||
|
.content main {
|
||||||
|
margin-inline-start: auto;
|
||||||
|
margin-inline-end: auto;
|
||||||
|
max-width: var(--content-max-width);
|
||||||
|
}
|
||||||
|
.content p { line-height: 1.45em; }
|
||||||
|
.content ol { line-height: 1.45em; }
|
||||||
|
.content ul { line-height: 1.45em; }
|
||||||
|
.content a { text-decoration: none; }
|
||||||
|
.content a:hover { text-decoration: underline; }
|
||||||
|
.content img, .content video { max-width: 100%; }
|
||||||
|
.content .header:link,
|
||||||
|
.content .header:visited {
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
.content .header:link,
|
||||||
|
.content .header:visited:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
margin: 0 auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
table td {
|
||||||
|
padding: 3px 20px;
|
||||||
|
border: 1px var(--table-border-color) solid;
|
||||||
|
}
|
||||||
|
table thead {
|
||||||
|
background: var(--table-header-bg);
|
||||||
|
}
|
||||||
|
table thead td {
|
||||||
|
font-weight: 700;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
table thead th {
|
||||||
|
padding: 3px 20px;
|
||||||
|
}
|
||||||
|
table thead tr {
|
||||||
|
border: 1px var(--table-header-bg) solid;
|
||||||
|
}
|
||||||
|
/* Alternate background colors for rows */
|
||||||
|
table tbody tr:nth-child(2n) {
|
||||||
|
background: var(--table-alternate-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 0 20px;
|
||||||
|
color: var(--fg);
|
||||||
|
background-color: var(--quote-bg);
|
||||||
|
border-block-start: .1em solid var(--quote-border);
|
||||||
|
border-block-end: .1em solid var(--quote-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning {
|
||||||
|
margin: 20px;
|
||||||
|
padding: 0 20px;
|
||||||
|
border-inline-start: 2px solid var(--warning-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning:before {
|
||||||
|
position: absolute;
|
||||||
|
width: 3rem;
|
||||||
|
height: 3rem;
|
||||||
|
margin-inline-start: calc(-1.5rem - 21px);
|
||||||
|
content: "ⓘ";
|
||||||
|
text-align: center;
|
||||||
|
background-color: var(--bg);
|
||||||
|
color: var(--warning-border);
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote .warning:before {
|
||||||
|
background-color: var(--quote-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
kbd {
|
||||||
|
background-color: var(--table-border-color);
|
||||||
|
border-radius: 4px;
|
||||||
|
border: solid 1px var(--theme-popup-border);
|
||||||
|
box-shadow: inset 0 -1px 0 var(--theme-hover);
|
||||||
|
display: inline-block;
|
||||||
|
font-size: var(--code-font-size);
|
||||||
|
font-family: var(--mono-font);
|
||||||
|
line-height: 10px;
|
||||||
|
padding: 4px 5px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
sup {
|
||||||
|
/* Set the line-height for superscript and footnote references so that there
|
||||||
|
isn't an awkward space appearing above lines that contain the footnote.
|
||||||
|
|
||||||
|
See https://github.com/rust-lang/mdBook/pull/2443#discussion_r1813773583
|
||||||
|
for an explanation.
|
||||||
|
*/
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footnote-definition {
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
/* The default spacing for a list is a little too large. */
|
||||||
|
.footnote-definition ul,
|
||||||
|
.footnote-definition ol {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
.footnote-definition > li {
|
||||||
|
/* Required to position the ::before target */
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.footnote-definition > li:target {
|
||||||
|
scroll-margin-top: 50vh;
|
||||||
|
}
|
||||||
|
.footnote-reference:target {
|
||||||
|
scroll-margin-top: 50vh;
|
||||||
|
}
|
||||||
|
/* Draws a border around the footnote (including the marker) when it is selected.
|
||||||
|
TODO: If there are multiple linkbacks, highlight which one you just came
|
||||||
|
from so you know which one to click.
|
||||||
|
*/
|
||||||
|
.footnote-definition > li:target::before {
|
||||||
|
border: 2px solid var(--footnote-highlight);
|
||||||
|
border-radius: 6px;
|
||||||
|
position: absolute;
|
||||||
|
top: -8px;
|
||||||
|
right: -8px;
|
||||||
|
bottom: -8px;
|
||||||
|
left: -32px;
|
||||||
|
pointer-events: none;
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
/* Pulses the footnote reference so you can quickly see where you left off reading.
|
||||||
|
This could use some improvement.
|
||||||
|
*/
|
||||||
|
@media not (prefers-reduced-motion) {
|
||||||
|
.footnote-reference:target {
|
||||||
|
animation: fn-highlight 0.8s;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fn-highlight {
|
||||||
|
from {
|
||||||
|
background-color: var(--footnote-highlight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltiptext {
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #333;
|
||||||
|
transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
|
||||||
|
left: -8px; /* Half of the width of the icon */
|
||||||
|
top: -35px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 5px 8px;
|
||||||
|
margin: 5px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
.tooltipped .tooltiptext {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chapter li.part-title {
|
||||||
|
color: var(--sidebar-fg);
|
||||||
|
margin: 5px 0px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-no-output {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
50
css/print.css
Normal file
50
css/print.css
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
#sidebar,
|
||||||
|
#menu-bar,
|
||||||
|
.nav-chapters,
|
||||||
|
.mobile-nav-chapters {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-wrapper.page-wrapper {
|
||||||
|
transform: none !important;
|
||||||
|
margin-inline-start: 0px;
|
||||||
|
overflow-y: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
max-width: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
overflow-y: initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
direction: ltr !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre > .buttons {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
a, a:visited, a:active, a:hover {
|
||||||
|
color: #4183c4;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
page-break-inside: avoid;
|
||||||
|
page-break-after: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre, code {
|
||||||
|
page-break-inside: avoid;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
display: none !important;
|
||||||
|
}
|
319
css/variables.css
Normal file
319
css/variables.css
Normal file
@ -0,0 +1,319 @@
|
|||||||
|
|
||||||
|
/* Globals */
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--sidebar-width: 300px;
|
||||||
|
--sidebar-resize-indicator-width: 8px;
|
||||||
|
--sidebar-resize-indicator-space: 2px;
|
||||||
|
--page-padding: 15px;
|
||||||
|
--content-max-width: 750px;
|
||||||
|
--menu-bar-height: 50px;
|
||||||
|
--mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace;
|
||||||
|
--code-font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Themes */
|
||||||
|
|
||||||
|
.ayu {
|
||||||
|
--bg: hsl(210, 25%, 8%);
|
||||||
|
--fg: #c5c5c5;
|
||||||
|
|
||||||
|
--sidebar-bg: #14191f;
|
||||||
|
--sidebar-fg: #c8c9db;
|
||||||
|
--sidebar-non-existant: #5c6773;
|
||||||
|
--sidebar-active: #ffb454;
|
||||||
|
--sidebar-spacer: #2d334f;
|
||||||
|
|
||||||
|
--scrollbar: var(--sidebar-fg);
|
||||||
|
|
||||||
|
--icons: #737480;
|
||||||
|
--icons-hover: #b7b9cc;
|
||||||
|
|
||||||
|
--links: #0096cf;
|
||||||
|
|
||||||
|
--inline-code-color: #ffb454;
|
||||||
|
|
||||||
|
--theme-popup-bg: #14191f;
|
||||||
|
--theme-popup-border: #5c6773;
|
||||||
|
--theme-hover: #191f26;
|
||||||
|
|
||||||
|
--quote-bg: hsl(226, 15%, 17%);
|
||||||
|
--quote-border: hsl(226, 15%, 22%);
|
||||||
|
|
||||||
|
--warning-border: #ff8e00;
|
||||||
|
|
||||||
|
--table-border-color: hsl(210, 25%, 13%);
|
||||||
|
--table-header-bg: hsl(210, 25%, 28%);
|
||||||
|
--table-alternate-bg: hsl(210, 25%, 11%);
|
||||||
|
|
||||||
|
--searchbar-border-color: #848484;
|
||||||
|
--searchbar-bg: #424242;
|
||||||
|
--searchbar-fg: #fff;
|
||||||
|
--searchbar-shadow-color: #d4c89f;
|
||||||
|
--searchresults-header-fg: #666;
|
||||||
|
--searchresults-border-color: #888;
|
||||||
|
--searchresults-li-bg: #252932;
|
||||||
|
--search-mark-bg: #e3b171;
|
||||||
|
|
||||||
|
--color-scheme: dark;
|
||||||
|
|
||||||
|
/* Same as `--icons` */
|
||||||
|
--copy-button-filter: invert(45%) sepia(6%) saturate(621%) hue-rotate(198deg) brightness(99%) contrast(85%);
|
||||||
|
/* Same as `--sidebar-active` */
|
||||||
|
--copy-button-filter-hover: invert(68%) sepia(55%) saturate(531%) hue-rotate(341deg) brightness(104%) contrast(101%);
|
||||||
|
|
||||||
|
--footnote-highlight: #2668a6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.coal {
|
||||||
|
--bg: hsl(200, 7%, 8%);
|
||||||
|
--fg: #98a3ad;
|
||||||
|
|
||||||
|
--sidebar-bg: #292c2f;
|
||||||
|
--sidebar-fg: #a1adb8;
|
||||||
|
--sidebar-non-existant: #505254;
|
||||||
|
--sidebar-active: #3473ad;
|
||||||
|
--sidebar-spacer: #393939;
|
||||||
|
|
||||||
|
--scrollbar: var(--sidebar-fg);
|
||||||
|
|
||||||
|
--icons: #43484d;
|
||||||
|
--icons-hover: #b3c0cc;
|
||||||
|
|
||||||
|
--links: #2b79a2;
|
||||||
|
|
||||||
|
--inline-code-color: #c5c8c6;
|
||||||
|
|
||||||
|
--theme-popup-bg: #141617;
|
||||||
|
--theme-popup-border: #43484d;
|
||||||
|
--theme-hover: #1f2124;
|
||||||
|
|
||||||
|
--quote-bg: hsl(234, 21%, 18%);
|
||||||
|
--quote-border: hsl(234, 21%, 23%);
|
||||||
|
|
||||||
|
--warning-border: #ff8e00;
|
||||||
|
|
||||||
|
--table-border-color: hsl(200, 7%, 13%);
|
||||||
|
--table-header-bg: hsl(200, 7%, 28%);
|
||||||
|
--table-alternate-bg: hsl(200, 7%, 11%);
|
||||||
|
|
||||||
|
--searchbar-border-color: #aaa;
|
||||||
|
--searchbar-bg: #b7b7b7;
|
||||||
|
--searchbar-fg: #000;
|
||||||
|
--searchbar-shadow-color: #aaa;
|
||||||
|
--searchresults-header-fg: #666;
|
||||||
|
--searchresults-border-color: #98a3ad;
|
||||||
|
--searchresults-li-bg: #2b2b2f;
|
||||||
|
--search-mark-bg: #355c7d;
|
||||||
|
|
||||||
|
--color-scheme: dark;
|
||||||
|
|
||||||
|
/* Same as `--icons` */
|
||||||
|
--copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%);
|
||||||
|
/* Same as `--sidebar-active` */
|
||||||
|
--copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%);
|
||||||
|
|
||||||
|
--footnote-highlight: #4079ae;
|
||||||
|
}
|
||||||
|
|
||||||
|
.light, html:not(.js) {
|
||||||
|
--bg: hsl(0, 0%, 100%);
|
||||||
|
--fg: hsl(0, 0%, 0%);
|
||||||
|
|
||||||
|
--sidebar-bg: #fafafa;
|
||||||
|
--sidebar-fg: hsl(0, 0%, 0%);
|
||||||
|
--sidebar-non-existant: #aaaaaa;
|
||||||
|
--sidebar-active: #1f1fff;
|
||||||
|
--sidebar-spacer: #f4f4f4;
|
||||||
|
|
||||||
|
--scrollbar: #8F8F8F;
|
||||||
|
|
||||||
|
--icons: #747474;
|
||||||
|
--icons-hover: #000000;
|
||||||
|
|
||||||
|
--links: #20609f;
|
||||||
|
|
||||||
|
--inline-code-color: #301900;
|
||||||
|
|
||||||
|
--theme-popup-bg: #fafafa;
|
||||||
|
--theme-popup-border: #cccccc;
|
||||||
|
--theme-hover: #e6e6e6;
|
||||||
|
|
||||||
|
--quote-bg: hsl(197, 37%, 96%);
|
||||||
|
--quote-border: hsl(197, 37%, 91%);
|
||||||
|
|
||||||
|
--warning-border: #ff8e00;
|
||||||
|
|
||||||
|
--table-border-color: hsl(0, 0%, 95%);
|
||||||
|
--table-header-bg: hsl(0, 0%, 80%);
|
||||||
|
--table-alternate-bg: hsl(0, 0%, 97%);
|
||||||
|
|
||||||
|
--searchbar-border-color: #aaa;
|
||||||
|
--searchbar-bg: #fafafa;
|
||||||
|
--searchbar-fg: #000;
|
||||||
|
--searchbar-shadow-color: #aaa;
|
||||||
|
--searchresults-header-fg: #666;
|
||||||
|
--searchresults-border-color: #888;
|
||||||
|
--searchresults-li-bg: #e4f2fe;
|
||||||
|
--search-mark-bg: #a2cff5;
|
||||||
|
|
||||||
|
--color-scheme: light;
|
||||||
|
|
||||||
|
/* Same as `--icons` */
|
||||||
|
--copy-button-filter: invert(45.49%);
|
||||||
|
/* Same as `--sidebar-active` */
|
||||||
|
--copy-button-filter-hover: invert(14%) sepia(93%) saturate(4250%) hue-rotate(243deg) brightness(99%) contrast(130%);
|
||||||
|
|
||||||
|
--footnote-highlight: #7e7eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navy {
|
||||||
|
--bg: hsl(226, 23%, 11%);
|
||||||
|
--fg: #bcbdd0;
|
||||||
|
|
||||||
|
--sidebar-bg: #282d3f;
|
||||||
|
--sidebar-fg: #c8c9db;
|
||||||
|
--sidebar-non-existant: #505274;
|
||||||
|
--sidebar-active: #2b79a2;
|
||||||
|
--sidebar-spacer: #2d334f;
|
||||||
|
|
||||||
|
--scrollbar: var(--sidebar-fg);
|
||||||
|
|
||||||
|
--icons: #737480;
|
||||||
|
--icons-hover: #b7b9cc;
|
||||||
|
|
||||||
|
--links: #2b79a2;
|
||||||
|
|
||||||
|
--inline-code-color: #c5c8c6;
|
||||||
|
|
||||||
|
--theme-popup-bg: #161923;
|
||||||
|
--theme-popup-border: #737480;
|
||||||
|
--theme-hover: #282e40;
|
||||||
|
|
||||||
|
--quote-bg: hsl(226, 15%, 17%);
|
||||||
|
--quote-border: hsl(226, 15%, 22%);
|
||||||
|
|
||||||
|
--warning-border: #ff8e00;
|
||||||
|
|
||||||
|
--table-border-color: hsl(226, 23%, 16%);
|
||||||
|
--table-header-bg: hsl(226, 23%, 31%);
|
||||||
|
--table-alternate-bg: hsl(226, 23%, 14%);
|
||||||
|
|
||||||
|
--searchbar-border-color: #aaa;
|
||||||
|
--searchbar-bg: #aeaec6;
|
||||||
|
--searchbar-fg: #000;
|
||||||
|
--searchbar-shadow-color: #aaa;
|
||||||
|
--searchresults-header-fg: #5f5f71;
|
||||||
|
--searchresults-border-color: #5c5c68;
|
||||||
|
--searchresults-li-bg: #242430;
|
||||||
|
--search-mark-bg: #a2cff5;
|
||||||
|
|
||||||
|
--color-scheme: dark;
|
||||||
|
|
||||||
|
/* Same as `--icons` */
|
||||||
|
--copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%);
|
||||||
|
/* Same as `--sidebar-active` */
|
||||||
|
--copy-button-filter-hover: invert(46%) sepia(20%) saturate(1537%) hue-rotate(156deg) brightness(85%) contrast(90%);
|
||||||
|
|
||||||
|
--footnote-highlight: #4079ae;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rust {
|
||||||
|
--bg: hsl(60, 9%, 87%);
|
||||||
|
--fg: #262625;
|
||||||
|
|
||||||
|
--sidebar-bg: #3b2e2a;
|
||||||
|
--sidebar-fg: #c8c9db;
|
||||||
|
--sidebar-non-existant: #505254;
|
||||||
|
--sidebar-active: #e69f67;
|
||||||
|
--sidebar-spacer: #45373a;
|
||||||
|
|
||||||
|
--scrollbar: var(--sidebar-fg);
|
||||||
|
|
||||||
|
--icons: #737480;
|
||||||
|
--icons-hover: #262625;
|
||||||
|
|
||||||
|
--links: #2b79a2;
|
||||||
|
|
||||||
|
--inline-code-color: #6e6b5e;
|
||||||
|
|
||||||
|
--theme-popup-bg: #e1e1db;
|
||||||
|
--theme-popup-border: #b38f6b;
|
||||||
|
--theme-hover: #99908a;
|
||||||
|
|
||||||
|
--quote-bg: hsl(60, 5%, 75%);
|
||||||
|
--quote-border: hsl(60, 5%, 70%);
|
||||||
|
|
||||||
|
--warning-border: #ff8e00;
|
||||||
|
|
||||||
|
--table-border-color: hsl(60, 9%, 82%);
|
||||||
|
--table-header-bg: #b3a497;
|
||||||
|
--table-alternate-bg: hsl(60, 9%, 84%);
|
||||||
|
|
||||||
|
--searchbar-border-color: #aaa;
|
||||||
|
--searchbar-bg: #fafafa;
|
||||||
|
--searchbar-fg: #000;
|
||||||
|
--searchbar-shadow-color: #aaa;
|
||||||
|
--searchresults-header-fg: #666;
|
||||||
|
--searchresults-border-color: #888;
|
||||||
|
--searchresults-li-bg: #dec2a2;
|
||||||
|
--search-mark-bg: #e69f67;
|
||||||
|
|
||||||
|
/* Same as `--icons` */
|
||||||
|
--copy-button-filter: invert(51%) sepia(10%) saturate(393%) hue-rotate(198deg) brightness(86%) contrast(87%);
|
||||||
|
/* Same as `--sidebar-active` */
|
||||||
|
--copy-button-filter-hover: invert(77%) sepia(16%) saturate(1798%) hue-rotate(328deg) brightness(98%) contrast(83%);
|
||||||
|
|
||||||
|
--footnote-highlight: #d3a17a;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html:not(.js) {
|
||||||
|
--bg: hsl(200, 7%, 8%);
|
||||||
|
--fg: #98a3ad;
|
||||||
|
|
||||||
|
--sidebar-bg: #292c2f;
|
||||||
|
--sidebar-fg: #a1adb8;
|
||||||
|
--sidebar-non-existant: #505254;
|
||||||
|
--sidebar-active: #3473ad;
|
||||||
|
--sidebar-spacer: #393939;
|
||||||
|
|
||||||
|
--scrollbar: var(--sidebar-fg);
|
||||||
|
|
||||||
|
--icons: #43484d;
|
||||||
|
--icons-hover: #b3c0cc;
|
||||||
|
|
||||||
|
--links: #2b79a2;
|
||||||
|
|
||||||
|
--inline-code-color: #c5c8c6;
|
||||||
|
|
||||||
|
--theme-popup-bg: #141617;
|
||||||
|
--theme-popup-border: #43484d;
|
||||||
|
--theme-hover: #1f2124;
|
||||||
|
|
||||||
|
--quote-bg: hsl(234, 21%, 18%);
|
||||||
|
--quote-border: hsl(234, 21%, 23%);
|
||||||
|
|
||||||
|
--warning-border: #ff8e00;
|
||||||
|
|
||||||
|
--table-border-color: hsl(200, 7%, 13%);
|
||||||
|
--table-header-bg: hsl(200, 7%, 28%);
|
||||||
|
--table-alternate-bg: hsl(200, 7%, 11%);
|
||||||
|
|
||||||
|
--searchbar-border-color: #aaa;
|
||||||
|
--searchbar-bg: #b7b7b7;
|
||||||
|
--searchbar-fg: #000;
|
||||||
|
--searchbar-shadow-color: #aaa;
|
||||||
|
--searchresults-header-fg: #666;
|
||||||
|
--searchresults-border-color: #98a3ad;
|
||||||
|
--searchresults-li-bg: #2b2b2f;
|
||||||
|
--search-mark-bg: #355c7d;
|
||||||
|
|
||||||
|
--color-scheme: dark;
|
||||||
|
|
||||||
|
/* Same as `--icons` */
|
||||||
|
--copy-button-filter: invert(26%) sepia(8%) saturate(575%) hue-rotate(169deg) brightness(87%) contrast(82%);
|
||||||
|
/* Same as `--sidebar-active` */
|
||||||
|
--copy-button-filter-hover: invert(36%) sepia(70%) saturate(503%) hue-rotate(167deg) brightness(98%) contrast(89%);
|
||||||
|
}
|
||||||
|
}
|
29
editor.js
Normal file
29
editor.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
"use strict";
|
||||||
|
window.editors = [];
|
||||||
|
(function(editors) {
|
||||||
|
if (typeof(ace) === 'undefined' || !ace) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array.from(document.querySelectorAll('.editable')).forEach(function(editable) {
|
||||||
|
let display_line_numbers = window.playground_line_numbers || false;
|
||||||
|
|
||||||
|
let editor = ace.edit(editable);
|
||||||
|
editor.setOptions({
|
||||||
|
highlightActiveLine: false,
|
||||||
|
showPrintMargin: false,
|
||||||
|
showLineNumbers: display_line_numbers,
|
||||||
|
showGutter: display_line_numbers,
|
||||||
|
maxLines: Infinity,
|
||||||
|
fontSize: "0.875em" // please adjust the font size of the code in general.css
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.$blockScrolling = Infinity;
|
||||||
|
|
||||||
|
editor.getSession().setMode("ace/mode/rust");
|
||||||
|
|
||||||
|
editor.originalCode = editor.getValue();
|
||||||
|
|
||||||
|
editors.push(editor);
|
||||||
|
});
|
||||||
|
})(window.editors);
|
10
elasticlunr.min.js
vendored
Normal file
10
elasticlunr.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
253
elegant-code-base.html
Normal file
253
elegant-code-base.html
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Small projects with Elegant code - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/elegant-code-base.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="small-projects-with-elegant-code-base"><a class="header" href="#small-projects-with-elegant-code-base">Small projects with Elegant code base</a></h1>
|
||||||
|
<p>Following questions come up weekly in online Rust discussions:</p>
|
||||||
|
<ul>
|
||||||
|
<li>I just finished reading The Book, what should I do next ?</li>
|
||||||
|
<li>What projects would you recommend to a Rust beginner?</li>
|
||||||
|
<li>Looking for small projects with an elegant code base</li>
|
||||||
|
<li>Codes that is easy to read and learn</li>
|
||||||
|
</ul>
|
||||||
|
<p>The answers to these questions are always <strong>Practice</strong>: doing some exercises, and then reading some small and excellent Rust projects.</p>
|
||||||
|
<p>This is precisely the goal of this book, so, collecting relative resourses and representing in <em>Rust By Practice</em> seems not a bad idea.</p>
|
||||||
|
<h3 id="1-ripgrep"><a class="header" href="#1-ripgrep">1. Ripgrep</a></h3>
|
||||||
|
<p>Answers for above questions usually came with <a href="https://github.com/BurntSushi/ripgrep"><code>ripgrep</code></a>, though I don't think it is a <strong>small</strong> project, but yes, go for it if you are not afraid to delve deep a bit.</p>
|
||||||
|
<h3 id="2-building-a-text-editor"><a class="header" href="#2-building-a-text-editor">2. Building a text editor</a></h3>
|
||||||
|
<p>Tutorial <a href="https://www.flenker.blog/hecto/"><code>https://www.flenker.blog/hecto/</code></a> will lead you to build a text editor from scratch.</p>
|
||||||
|
<h3 id="3-ncspot"><a class="header" href="#3-ncspot">3. Ncspot</a></h3>
|
||||||
|
<p><a href="https://github.com/hrkfdn/ncspot">Ncspot</a>, a terminal Spotify client. Small, simple, well organized and async, it's good for learning.</p>
|
||||||
|
<h3 id="4-command-line-rust"><a class="header" href="#4-command-line-rust">4. Command Line Rust</a></h3>
|
||||||
|
<p><a href="https://github.com/kyclark/command-line-rust">This project</a> is for the book <code>Command-Line Rust(O'Reily)</code>, it will show you how to write small CLIs (clones of <code>head</code>, <code>cat</code>, <code>ls</code>).</p>
|
||||||
|
<h3 id="5-pngme-book"><a class="header" href="#5-pngme-book">5. pngme book</a></h3>
|
||||||
|
<p><a href="https://jrdngr.github.io/pngme_book/">This book</a> will guide you to make a command line program that lets you hide secret messages in PNG files. The primary goal here is to get you writing code. The secondary goal is to get you reading documentation.</p>
|
||||||
|
<h3 id="6-writing-an-os-in-rust"><a class="header" href="#6-writing-an-os-in-rust">6. Writing an OS in Rust</a></h3>
|
||||||
|
<p><a href="https://os.phil-opp.com">This blog series</a> creates a small operating system in the Rust programming language. Each post is a small tutorial and includes all needed code, so you can follow along if you like. The source code is also available in the corresponding <a href="https://github.com/phil-opp/blog_os">Github repository</a>.</p>
|
||||||
|
<h3 id="7-codecraftersio-build-your-own-git-docker-sqlite-or-redis"><a class="header" href="#7-codecraftersio-build-your-own-git-docker-sqlite-or-redis">7. CodeCrafters.io: Build your own Git, Docker, SQLite, or Redis</a></h3>
|
||||||
|
<p>On <a href="https://codecrafters.io/for/rust">CodeCrafters</a>, you can recreate your favorite developer tools from scratch. It's a hands-on, minimally-guided approach to master Rust, while appreciating the internals and documentation of popular technology that we use every day.</p>
|
||||||
|
<h3 id="8-mini-redis"><a class="header" href="#8-mini-redis">8. mini-redis</a></h3>
|
||||||
|
<p><a href="https://github.com/tokio-rs/mini-redis">mini-redis</a> is an incomplete Redis client and server implementation using tokio, it has decent code base and detail explanations, very suitable for learning Rust and asynchronous programming.</p>
|
||||||
|
<h3 id="9-writing-interpreters-in-rust"><a class="header" href="#9-writing-interpreters-in-rust">9. Writing Interpreters in Rust</a></h3>
|
||||||
|
<p><a href="https://rust-hosted-langs.github.io/book/">This online book</a> will walk through the basics of interpreted language implementation in Rust with a focus on the challenges that are specific to using Rust.</p>
|
||||||
|
<hr />
|
||||||
|
<p><strong>To be continued...</strong></p>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="why-exercise.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="variables.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="why-exercise.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="variables.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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
224
errors.html
Normal file
224
errors.html
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Errors TODO - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/errors.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="errors"><a class="header" href="#errors">Errors</a></h1>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="global-variables.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="unsafe/intro.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="global-variables.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="unsafe/intro.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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
favicon.png
Normal file
BIN
favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
22
favicon.svg
Normal file
22
favicon.svg
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 199.7 184.2">
|
||||||
|
<style>
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
svg { fill: white; }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<path d="M189.5,36.8c0.2,2.8,0,5.1-0.6,6.8L153,162c-0.6,2.1-2,3.7-4.2,5c-2.2,1.2-4.4,1.9-6.7,1.9H31.4c-9.6,0-15.3-2.8-17.3-8.4
|
||||||
|
c-0.8-2.2-0.8-3.9,0.1-5.2c0.9-1.2,2.4-1.8,4.6-1.8H123c7.4,0,12.6-1.4,15.4-4.1s5.7-8.9,8.6-18.4l32.9-108.6
|
||||||
|
c1.8-5.9,1-11.1-2.2-15.6S169.9,0,164,0H72.7c-1,0-3.1,0.4-6.1,1.1l0.1-0.4C64.5,0.2,62.6,0,61,0.1s-3,0.5-4.3,1.4
|
||||||
|
c-1.3,0.9-2.4,1.8-3.2,2.8S52,6.5,51.2,8.1c-0.8,1.6-1.4,3-1.9,4.3s-1.1,2.7-1.8,4.2c-0.7,1.5-1.3,2.7-2,3.7c-0.5,0.6-1.2,1.5-2,2.5
|
||||||
|
s-1.6,2-2.2,2.8s-0.9,1.5-1.1,2.2c-0.2,0.7-0.1,1.8,0.2,3.2c0.3,1.4,0.4,2.4,0.4,3.1c-0.3,3-1.4,6.9-3.3,11.6
|
||||||
|
c-1.9,4.7-3.6,8.1-5.1,10.1c-0.3,0.4-1.2,1.3-2.6,2.7c-1.4,1.4-2.3,2.6-2.6,3.7c-0.3,0.4-0.3,1.5-0.1,3.4c0.3,1.8,0.4,3.1,0.3,3.8
|
||||||
|
c-0.3,2.7-1.3,6.3-3,10.8c-1.7,4.5-3.4,8.2-5,11c-0.2,0.5-0.9,1.4-2,2.8c-1.1,1.4-1.8,2.5-2,3.4c-0.2,0.6-0.1,1.8,0.1,3.4
|
||||||
|
c0.2,1.6,0.2,2.8-0.1,3.6c-0.6,3-1.8,6.7-3.6,11c-1.8,4.3-3.6,7.9-5.4,11c-0.5,0.8-1.1,1.7-2,2.8c-0.8,1.1-1.5,2-2,2.8
|
||||||
|
s-0.8,1.6-1,2.5c-0.1,0.5,0,1.3,0.4,2.3c0.3,1.1,0.4,1.9,0.4,2.6c-0.1,1.1-0.2,2.6-0.5,4.4c-0.2,1.8-0.4,2.9-0.4,3.2
|
||||||
|
c-1.8,4.8-1.7,9.9,0.2,15.2c2.2,6.2,6.2,11.5,11.9,15.8c5.7,4.3,11.7,6.4,17.8,6.4h110.7c5.2,0,10.1-1.7,14.7-5.2s7.7-7.8,9.2-12.9
|
||||||
|
l33-108.6c1.8-5.8,1-10.9-2.2-15.5C194.9,39.7,192.6,38,189.5,36.8z M59.6,122.8L73.8,80c0,0,7,0,10.8,0s28.8-1.7,25.4,17.5
|
||||||
|
c-3.4,19.2-18.8,25.2-36.8,25.4S59.6,122.8,59.6,122.8z M78.6,116.8c4.7-0.1,18.9-2.9,22.1-17.1S89.2,86.3,89.2,86.3l-8.9,0
|
||||||
|
l-10.2,30.5C70.2,116.9,74,116.9,78.6,116.8z M75.3,68.7L89,26.2h9.8l0.8,34l23.6-34h9.9l-13.6,42.5h-7.1l12.5-35.4l-24.5,35.4h-6.8
|
||||||
|
l-0.8-35L82,68.7H75.3z"/>
|
||||||
|
</svg>
|
||||||
|
<!-- Original image Copyright Dave Gandy — CC BY 4.0 License -->
|
After Width: | Height: | Size: 1.8 KiB |
248
fight-compiler/borrowing.html
Normal file
248
fight-compiler/borrowing.html
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Borrowing - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/fight-compiler/borrowing.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="borrowing"><a class="header" href="#borrowing">Borrowing</a></h1>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// FIX the error without removing any code line
|
||||||
|
struct test {
|
||||||
|
list: Vec<i32>,
|
||||||
|
a: i32
|
||||||
|
}
|
||||||
|
|
||||||
|
impl test {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
test { list:vec![1,2,3,4,5,6,7], a:0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self) {
|
||||||
|
for i in self.list.iter() {
|
||||||
|
self.do_something(*i)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn do_something(&mut self, n: i32) {
|
||||||
|
self.a = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/fight-compiler/borrowing.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../fight-compiler/intro.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||||
|
<i class="fa fa-angle-left"></i>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
<div style="clear: both"></div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||||
|
<a rel="prev" href="../fight-compiler/intro.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||||
|
<i class="fa fa-angle-left"></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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
226
fight-compiler/intro.html
Normal file
226
fight-compiler/intro.html
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Fighting with Compiler - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/fight-compiler/intro.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="fighting-with-compiler"><a class="header" href="#fighting-with-compiler">Fighting with Compiler</a></h1>
|
||||||
|
<p>Fighting with compiler is very common in our daily coding, especially for those unfamiliar with Rust.</p>
|
||||||
|
<p>This chapter will provide some exercises to help us avoid such cases to lower the steep learning curve.</p>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../std/String.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="../fight-compiler/borrowing.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="../std/String.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="../fight-compiler/borrowing.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
466
flow-control.html
Normal file
466
flow-control.html
Normal file
@ -0,0 +1,466 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Flow Control - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/flow-control.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="flow-control"><a class="header" href="#flow-control">Flow control</a></h1>
|
||||||
|
<h3 id="ifelse"><a class="header" href="#ifelse">If/else</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blanks
|
||||||
|
fn main() {
|
||||||
|
let n = 5;
|
||||||
|
|
||||||
|
if n < 0 {
|
||||||
|
println!("{} is negative", n);
|
||||||
|
} __ n > 0 {
|
||||||
|
println!("{} is positive", n);
|
||||||
|
} __ {
|
||||||
|
println!("{} is zero", n);
|
||||||
|
}
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟 <code>If/else</code> expression can be used in assignments.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the errors
|
||||||
|
fn main() {
|
||||||
|
let n = 5;
|
||||||
|
|
||||||
|
let big_n =
|
||||||
|
if n < 10 && n > -10 {
|
||||||
|
println!(", and is a small number, increase ten-fold");
|
||||||
|
|
||||||
|
10 * n
|
||||||
|
} else {
|
||||||
|
println!(", and is a big number, halve the number");
|
||||||
|
|
||||||
|
n / 2.0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{} -> {}", n, big_n);
|
||||||
|
} </code></pre></pre>
|
||||||
|
<h3 id="for"><a class="header" href="#for">For</a></h3>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟 The <code>for in</code> construct can be used to iterate through an Iterator, e.g a range <code>a..b</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
for n in 1..=100 { // modify this line to make the code work
|
||||||
|
if n == 100 {
|
||||||
|
panic!("NEVER LET THIS RUN")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the errors without adding or removing lines
|
||||||
|
fn main() {
|
||||||
|
let names = [String::from("liming"),String::from("hanmeimei")];
|
||||||
|
for name in names {
|
||||||
|
// Do something with name...
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{:?}", names);
|
||||||
|
|
||||||
|
let numbers = [1, 2, 3];
|
||||||
|
// The elements in numbers are Copy,so there is no move here
|
||||||
|
for n in numbers {
|
||||||
|
// Do something with n...
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{:?}", numbers);
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
let a = [4, 3, 2, 1];
|
||||||
|
|
||||||
|
// Iterate the indexing and value in 'a'
|
||||||
|
for (i,v) in a.__ {
|
||||||
|
println!("The {}th element is {}",i+1,v);
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="while"><a class="header" href="#while">While</a></h3>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟 The <code>while</code> keyword can be used to run a loop when a condition is true.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blanks to make the last println! work !
|
||||||
|
fn main() {
|
||||||
|
// A counter variable
|
||||||
|
let mut n = 1;
|
||||||
|
|
||||||
|
// Loop while the condition is true
|
||||||
|
while n __ 10 {
|
||||||
|
if n % 15 == 0 {
|
||||||
|
println!("fizzbuzz");
|
||||||
|
} else if n % 3 == 0 {
|
||||||
|
println!("fizz");
|
||||||
|
} else if n % 5 == 0 {
|
||||||
|
println!("buzz");
|
||||||
|
} else {
|
||||||
|
println!("{}", n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("n reached {}, so loop is over",n);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="continue-and-break"><a class="header" href="#continue-and-break">Continue and break</a></h3>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟 Use <code>break</code> to break the loop.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blank
|
||||||
|
fn main() {
|
||||||
|
let mut n = 0;
|
||||||
|
for i in 0..=100 {
|
||||||
|
if n == 66 {
|
||||||
|
__
|
||||||
|
}
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(n, 66);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟 <code>continue</code> will skip over the remaining code in current iteration and go to the next iteration.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blanks
|
||||||
|
fn main() {
|
||||||
|
let mut n = 0;
|
||||||
|
for i in 0..=100 {
|
||||||
|
if n != 66 {
|
||||||
|
n+=1;
|
||||||
|
__;
|
||||||
|
}
|
||||||
|
|
||||||
|
__
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(n, 66);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="loop"><a class="header" href="#loop">Loop</a></h3>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟🌟 Loop is usually used together with <code>break</code> or <code>continue</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blanks
|
||||||
|
fn main() {
|
||||||
|
let mut count = 0u32;
|
||||||
|
|
||||||
|
println!("Let's count until infinity!");
|
||||||
|
|
||||||
|
// Infinite loop
|
||||||
|
loop {
|
||||||
|
count += 1;
|
||||||
|
|
||||||
|
if count == 3 {
|
||||||
|
println!("three");
|
||||||
|
|
||||||
|
// Skip the rest of this iteration
|
||||||
|
__;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", count);
|
||||||
|
|
||||||
|
if count == 5 {
|
||||||
|
println!("OK, that's enough");
|
||||||
|
|
||||||
|
__;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(count, 5);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="10">
|
||||||
|
<li>🌟🌟 Loop is an expression, so we can use it with <code>break</code> to return a value</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blank
|
||||||
|
fn main() {
|
||||||
|
let mut counter = 0;
|
||||||
|
|
||||||
|
let result = loop {
|
||||||
|
counter += 1;
|
||||||
|
|
||||||
|
if counter == 10 {
|
||||||
|
__;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(result, 20);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="11">
|
||||||
|
<li>🌟🌟🌟 It's possible to break or continue outer loops when dealing with nested loops. In these cases, the loops must be annotated with some 'label, and the label must be passed to the break/continue statement.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blank
|
||||||
|
fn main() {
|
||||||
|
let mut count = 0;
|
||||||
|
'outer: loop {
|
||||||
|
'inner1: loop {
|
||||||
|
if count >= 20 {
|
||||||
|
// This would break only the inner1 loop
|
||||||
|
break 'inner1; // `break` is also works.
|
||||||
|
}
|
||||||
|
count += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
count += 5;
|
||||||
|
|
||||||
|
'inner2: loop {
|
||||||
|
if count >= 30 {
|
||||||
|
// This breaks the outer loop
|
||||||
|
break 'outer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will continue the outer loop
|
||||||
|
continue 'outer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(count == __);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="compound-types/enum.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="pattern-match/intro.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="compound-types/enum.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="pattern-match/intro.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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
202
fonts/OPEN-SANS-LICENSE.txt
Normal file
202
fonts/OPEN-SANS-LICENSE.txt
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
93
fonts/SOURCE-CODE-PRO-LICENSE.txt
Normal file
93
fonts/SOURCE-CODE-PRO-LICENSE.txt
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
http://scripts.sil.org/OFL
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------------------------------------------
|
||||||
|
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||||
|
-----------------------------------------------------------
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
"Font Software" refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
"Reserved Font Name" refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
"Original Version" refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
"Author" refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the Font
|
||||||
|
Software, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the Font Software nor any of its individual components,
|
||||||
|
in Original or Modified Versions, may be sold by itself.
|
||||||
|
|
||||||
|
2) Original or Modified Versions of the Font Software may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No Modified Version of the Font Software may use the Reserved Font
|
||||||
|
Name(s) unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||||
|
Software shall not be used to promote, endorse or advertise any
|
||||||
|
Modified Version, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The Font Software, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the Font Software.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
100
fonts/fonts.css
Normal file
100
fonts/fonts.css
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */
|
||||||
|
/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */
|
||||||
|
|
||||||
|
/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
src: local('Open Sans Light'), local('OpenSans-Light'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-300.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 300;
|
||||||
|
src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-300italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Open Sans Regular'), local('OpenSans-Regular'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-regular.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Open Sans Italic'), local('OpenSans-Italic'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-600.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 600;
|
||||||
|
src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-600italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: local('Open Sans Bold'), local('OpenSans-Bold'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-700.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 700;
|
||||||
|
src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-700italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 800;
|
||||||
|
src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-800.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Open Sans';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 800;
|
||||||
|
src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'),
|
||||||
|
url('../fonts/open-sans-v17-all-charsets-800italic.woff2') format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Source Code Pro';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: url('../fonts/source-code-pro-v11-all-charsets-500.woff2') format('woff2');
|
||||||
|
}
|
BIN
fonts/open-sans-v17-all-charsets-300.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-300.woff2
Normal file
Binary file not shown.
BIN
fonts/open-sans-v17-all-charsets-300italic.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-300italic.woff2
Normal file
Binary file not shown.
BIN
fonts/open-sans-v17-all-charsets-600.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-600.woff2
Normal file
Binary file not shown.
BIN
fonts/open-sans-v17-all-charsets-600italic.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-600italic.woff2
Normal file
Binary file not shown.
BIN
fonts/open-sans-v17-all-charsets-700.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-700.woff2
Normal file
Binary file not shown.
BIN
fonts/open-sans-v17-all-charsets-700italic.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-700italic.woff2
Normal file
Binary file not shown.
BIN
fonts/open-sans-v17-all-charsets-800.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-800.woff2
Normal file
Binary file not shown.
BIN
fonts/open-sans-v17-all-charsets-800italic.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-800italic.woff2
Normal file
Binary file not shown.
BIN
fonts/open-sans-v17-all-charsets-italic.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-italic.woff2
Normal file
Binary file not shown.
BIN
fonts/open-sans-v17-all-charsets-regular.woff2
Normal file
BIN
fonts/open-sans-v17-all-charsets-regular.woff2
Normal file
Binary file not shown.
BIN
fonts/source-code-pro-v11-all-charsets-500.woff2
Normal file
BIN
fonts/source-code-pro-v11-all-charsets-500.woff2
Normal file
Binary file not shown.
363
formatted-output/debug-display.html
Normal file
363
formatted-output/debug-display.html
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Debug and Display - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/formatted-output/debug-display.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="debug-and-display"><a class="header" href="#debug-and-display">Debug and Display</a></h1>
|
||||||
|
<p>All types which want to be printable must implement the <code>std::fmt</code> formatting trait: <code>std::fmt::Debug</code> or <code>std::fmt::Display</code>.</p>
|
||||||
|
<p>Automatic implementations are only provided for types such as in the <code>std</code> library. All others have to be manually implemented.</p>
|
||||||
|
<h2 id="debug"><a class="header" href="#debug">Debug</a></h2>
|
||||||
|
<p>The implementation of <code>Debug</code> is very straightforward: All types can <code>derive</code> the <code>std::fmt::Debug</code> implementation. This is not true for <code>std::fmt::Display</code> which must be manually implemented.</p>
|
||||||
|
<p><code>{:?}</code> must be used to print out the type which has implemented the <code>Debug</code> trait.</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>// This structure cannot be printed either with `fmt::Display` or
|
||||||
|
// with `fmt::Debug`.
|
||||||
|
struct UnPrintable(i32);
|
||||||
|
|
||||||
|
// To make this struct printable with `fmt::Debug`, we can derive the automatic implementations provided by Rust
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct DebugPrintable(i32);
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
/* Fill in the blanks and Fix the errors */
|
||||||
|
struct Structure(i32);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Types in std and Rust have implemented the fmt::Debug trait
|
||||||
|
println!("__ months in a year.", 12);
|
||||||
|
|
||||||
|
println!("Now __ will print!", Structure(3));
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟 So <code>fmt::Debug</code> definitely makes one type printable, but sacrifices some elegance. Maybe we can get more elegant by replacing <code>{:?}</code> with something else( but not <code>{}</code> !)</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">#[derive(Debug)]
|
||||||
|
struct Person {
|
||||||
|
name: String,
|
||||||
|
age: u8
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let person = Person { name: "Sunface".to_string(), age: 18 };
|
||||||
|
|
||||||
|
/* Make it output:
|
||||||
|
Person {
|
||||||
|
name: "Sunface",
|
||||||
|
age: 18,
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
println!("{:?}", person);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟 We can also manually implement <code>Debug</code> trait for our types</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Structure(i32);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Deep(Structure);
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// The problem with `derive` is there is no control over how
|
||||||
|
// the results look. What if I want this to just show a `7`?
|
||||||
|
|
||||||
|
/* Make it print: Now 7 will print! */
|
||||||
|
println!("Now {:?} will print!", Deep(Structure(7)));
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="display"><a class="header" href="#display">Display</a></h2>
|
||||||
|
<p>Yeah, <code>Debug</code> is simple and easy to use. But sometimes we want to customize the output appearance of our type. This is where <code>Display</code> really shines.</p>
|
||||||
|
<p>Unlike <code>Debug</code>, there is no way to derive the implementation of the <code>Display</code> trait, we have to manually implement it.</p>
|
||||||
|
<p>Another thing to note: the placeholder for <code>Display</code> is <code>{}</code> not <code>{:?}</code>.</p>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
/* Make it work*/
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
struct Point2D {
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Point2D {
|
||||||
|
/* Implement.. */
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Point2D {
|
||||||
|
/* Implement.. */
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let point = Point2D { x: 3.3, y: 7.2 };
|
||||||
|
assert_eq!(format!("{}",point), "Display: 3.3 + 7.2i");
|
||||||
|
assert_eq!(format!("{:?}",point), "Debug: Complex { real: 3.3, imag: 7.2 }");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="-operator"><a class="header" href="#-operator"><code>?</code> operator</a></h3>
|
||||||
|
<p>Implementing <code>fmt::Display</code> for a structure whose elements must be handled separately is tricky. The problem is each <code>write!</code> generates a <code>fmt::Result</code> which must be handled in the same place.</p>
|
||||||
|
<p>Fortunately, Rust provides the <code>?</code> operator to help us eliminate some unnecessary codes for dealing with <code>fmt::Result</code>.</p>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
/* Make it work */
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
struct List(Vec<i32>);
|
||||||
|
|
||||||
|
impl fmt::Display for List {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
// Extract the value using tuple indexing,
|
||||||
|
// and create a reference to `vec`.
|
||||||
|
let vec = &self.0;
|
||||||
|
|
||||||
|
write!(f, "[")?;
|
||||||
|
|
||||||
|
// Iterate over `v` in `vec` while enumerating the iteration
|
||||||
|
// count in `count`.
|
||||||
|
for (count, v) in vec.iter().enumerate() {
|
||||||
|
// For every element except the first, add a comma.
|
||||||
|
// Use the ? operator to return on errors.
|
||||||
|
if count != 0 { write!(f, ", ")?; }
|
||||||
|
write!(f, "{}", v)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the opened bracket and return a fmt::Result value.
|
||||||
|
write!(f, "]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let v = List(vec![1, 2, 3]);
|
||||||
|
assert_eq!(format!("{}",v), "[0: 1, 1: 2, 2: 3]");
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/formatted-output/debug-display.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../formatted-output/println.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="../formatted-output/formatting.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="../formatted-output/println.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="../formatted-output/formatting.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
373
formatted-output/formatting.html
Normal file
373
formatted-output/formatting.html
Normal file
@ -0,0 +1,373 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>formating - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/formatted-output/formatting.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="formatting"><a class="header" href="#formatting">Formatting</a></h1>
|
||||||
|
<h2 id="positional-arguments"><a class="header" href="#positional-arguments">Positional arguments</a></h2>
|
||||||
|
<p>1.🌟🌟</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blanks */
|
||||||
|
fn main() {
|
||||||
|
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob"); // => Alice, this is Bob. Bob, this is Alice
|
||||||
|
assert_eq!(format!("{1}{0}", 1, 2), __);
|
||||||
|
assert_eq!(format!(__, 1, 2), "2112");
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="named-arguments"><a class="header" href="#named-arguments">Named arguments</a></h2>
|
||||||
|
<p>2.🌟🌟</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
println!("{argument}", argument = "test"); // => "test"
|
||||||
|
|
||||||
|
/* Fill in the blanks */
|
||||||
|
assert_eq!(format!("{name}{}", 1, __), "21");
|
||||||
|
assert_eq!(format!(__,a = "a", b = 'b', c = 3 ), "a 3 b");
|
||||||
|
|
||||||
|
/* Fix the error */
|
||||||
|
// Named argument must be placed after other arguments
|
||||||
|
println!("{abc} {1}", abc = "def", 2);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="padding-with-string"><a class="header" href="#padding-with-string">Padding with string</a></h2>
|
||||||
|
<p>3.🌟🌟 By default, you can pad string with spaces</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
// The following two are padding with 5 spaces
|
||||||
|
println!("Hello {:5}!", "x"); // => "Hello x !"
|
||||||
|
println!("Hello {:1$}!", "x", 5); // => "Hello x !"
|
||||||
|
|
||||||
|
/* Fill in the blanks */
|
||||||
|
assert_eq!(format!("Hello __!", 5, "x"), "Hello x !");
|
||||||
|
assert_eq!(format!("Hello __!", "x", width = 5), "Hello x !");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>4.🌟🌟🌟 Left align, right align, pad with specified characters.</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
// Left align
|
||||||
|
println!("Hello {:<5}!", "x"); // => Hello x !
|
||||||
|
// Right align
|
||||||
|
assert_eq!(format!("Hello __!", "x"), "Hello x!");
|
||||||
|
// Center align
|
||||||
|
assert_eq!(format!("Hello __!", "x"), "Hello x !");
|
||||||
|
|
||||||
|
// Left align, pad with '&'
|
||||||
|
assert_eq!(format!("Hello {:&<5}!", "x"), __);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>5.🌟🌟 You can pad numbers with extra zeros.</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
println!("Hello {:5}!", 5); // => Hello 5!
|
||||||
|
println!("Hello {:+}!", 5); // => Hello +5!
|
||||||
|
println!("Hello {:05}!", 5); // => Hello 00005!
|
||||||
|
println!("Hello {:05}!", -5); // => Hello -0005!
|
||||||
|
|
||||||
|
/* Fill in the blank */
|
||||||
|
assert!(format!("{number:0>width$}", number=1, width=6) == __);
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
;}</code></pre></pre>
|
||||||
|
<h2 id="precision"><a class="header" href="#precision">Precision</a></h2>
|
||||||
|
<p>6.🌟🌟 Floating point precision</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
/* Fill in the blanks */
|
||||||
|
fn main() {
|
||||||
|
let v = 3.1415926;
|
||||||
|
|
||||||
|
println!("{:.1$}", v, 4); // same as {:.4} => 3.1416
|
||||||
|
|
||||||
|
assert_eq!(format!("__", v), "3.14");
|
||||||
|
assert_eq!(format!("__", v), "+3.14");
|
||||||
|
assert_eq!(format!("__", v), "3");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>7.🌟🌟🌟 String length</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
let s = "Hello, world!";
|
||||||
|
|
||||||
|
println!("{0:.5}", s); // => Hello
|
||||||
|
|
||||||
|
assert_eq!(format!("Hello __!", 3, "abcdefg"), "Hello abc!");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="binary-octal-hex"><a class="header" href="#binary-octal-hex">Binary, octal, hex</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>format!("{}", foo) -> "3735928559"</li>
|
||||||
|
<li>format!("0x{:X}", foo) -> "0xDEADBEEF"</li>
|
||||||
|
<li>format!("0o{:o}", foo) -> "0o33653337357"</li>
|
||||||
|
</ul>
|
||||||
|
<p>8.🌟🌟</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
assert_eq!(format!("__", 27), "0b11011");
|
||||||
|
assert_eq!(format!("__", 27), "0o33");
|
||||||
|
assert_eq!(format!("__", 27), "0x1b");
|
||||||
|
assert_eq!(format!("__", 27), "0x1B");
|
||||||
|
|
||||||
|
println!("{:x}!", 27); // Hex with no prefix => 1b
|
||||||
|
|
||||||
|
println!("{:#010b}", 27); // Pad binary with 0, width = 10, => 0b00011011
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="capture-the-environment"><a class="header" href="#capture-the-environment">Capture the environment</a></h2>
|
||||||
|
<p>9.🌟🌟🌟</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn get_person() -> String {
|
||||||
|
String::from("sunface")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_format() -> (usize, usize) {
|
||||||
|
(4, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let person = get_person();
|
||||||
|
println!("Hello, {person}!");
|
||||||
|
|
||||||
|
let (width, precision) = get_format();
|
||||||
|
let scores = [("sunface", 99.12), ("jack", 60.34)];
|
||||||
|
/* Make it print:
|
||||||
|
sunface: 99.1
|
||||||
|
jack: 60.3
|
||||||
|
*/
|
||||||
|
for (name, score) in scores {
|
||||||
|
println!("{name}: __");
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="others"><a class="header" href="#others">Others</a></h2>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
// Exponent
|
||||||
|
println!("{:2e}", 1000000000); // => 1e9
|
||||||
|
println!("{:2E}", 1000000000); // => 1E9
|
||||||
|
|
||||||
|
// Pointer address
|
||||||
|
let v= vec![1, 2, 3];
|
||||||
|
println!("{:p}", v.as_ptr()); // => 0x600002324050
|
||||||
|
|
||||||
|
// Escape
|
||||||
|
println!("Hello {{}}"); // => Hello {}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/formatted-output/formatting.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../formatted-output/debug-display.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="../lifetime/intro.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="../formatted-output/debug-display.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="../lifetime/intro.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
284
formatted-output/intro.html
Normal file
284
formatted-output/intro.html
Normal file
@ -0,0 +1,284 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Formatted output - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/formatted-output/intro.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="formatted-output"><a class="header" href="#formatted-output">Formatted output</a></h1>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable ignore mdbook-runnable edition2021">fn main() {
|
||||||
|
// In general, the `{}` will be automatically replaced with any
|
||||||
|
// arguments. These will be stringified.
|
||||||
|
println!("{} days", 31);
|
||||||
|
|
||||||
|
// Without a suffix, 31 becomes an i32. You can change what type 31 is
|
||||||
|
// by providing a suffix. The number 31i64 for example has the type i64.
|
||||||
|
|
||||||
|
// There are various optional patterns this works with. Positional
|
||||||
|
// arguments can be used.
|
||||||
|
println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");
|
||||||
|
|
||||||
|
// As can named arguments.
|
||||||
|
println!("{subject} {verb} {object}",
|
||||||
|
object="the lazy dog",
|
||||||
|
subject="the quick brown fox",
|
||||||
|
verb="jumps over");
|
||||||
|
|
||||||
|
// Special formatting can be specified after a `:`.
|
||||||
|
println!("{} of {:b} people know binary, the other half doesn't", 1, 2);
|
||||||
|
|
||||||
|
// You can right-align text with a specified width. This will output
|
||||||
|
// " 1". 5 white spaces and a "1".
|
||||||
|
println!("{number:>width$}", number=1, width=6);
|
||||||
|
|
||||||
|
// You can pad numbers with extra zeroes. This will output "000001".
|
||||||
|
println!("{number:0>width$}", number=1, width=6);
|
||||||
|
|
||||||
|
// Rust even checks to make sure the correct number of arguments are
|
||||||
|
// used.
|
||||||
|
println!("My name is {0}, {1} {0}", "Bond");
|
||||||
|
// FIXME ^ Add the missing argument: "James"
|
||||||
|
|
||||||
|
// Create a structure named `Structure` which contains an `i32`.
|
||||||
|
#[allow(dead_code)]
|
||||||
|
struct Structure(i32);
|
||||||
|
|
||||||
|
// However, custom types such as this structure require more complicated
|
||||||
|
// handling. This will not work.
|
||||||
|
println!("This struct `{}` won't print...", Structure(3));
|
||||||
|
// FIXME ^ Comment out this line.
|
||||||
|
|
||||||
|
// For Rust 1.58 and above, you can directly capture the argument from
|
||||||
|
// surrounding variable. Just like the above, this will output
|
||||||
|
// " 1". 5 white spaces and a "1".
|
||||||
|
let number: f64 = 1.0;
|
||||||
|
let width: usize = 6;
|
||||||
|
println!("{number:>width$}");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>[<code>std::fmt</code>][fmt] contains many [<code>traits</code>][traits] which govern the display
|
||||||
|
of text. The base form of two important ones are listed below:</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>fmt::Debug</code>: Uses the <code>{:?}</code> marker. Format text for debugging purposes.</li>
|
||||||
|
<li><code>fmt::Display</code>: Uses the <code>{}</code> marker. Format text in a more elegant, user
|
||||||
|
friendly fashion.</li>
|
||||||
|
</ul>
|
||||||
|
<p>Here, we used <code>fmt::Display</code> because the std library provides implementations
|
||||||
|
for these types. To print text for custom types, more steps are required.</p>
|
||||||
|
<p>Implementing the <code>fmt::Display</code> trait automatically implements the
|
||||||
|
[<code>ToString</code>] trait which allows us to [convert] the type to [<code>String</code>][string].</p>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../comments-docs.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="../formatted-output/println.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="../comments-docs.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="../formatted-output/println.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
258
formatted-output/println.html
Normal file
258
formatted-output/println.html
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>println! and format! - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/formatted-output/println.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="println-and-format"><a class="header" href="#println-and-format">println! and format!</a></h1>
|
||||||
|
<p>Printing is handled by a series of [<code>macros</code>][macros] defined in [<code>std::fmt</code>][fmt]
|
||||||
|
Some of which include:</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>format!</code>: write formatted text to [<code>String</code>][string]</li>
|
||||||
|
<li><code>print!</code>: same as <code>format!</code> but the text is printed to the console (io::stdout).</li>
|
||||||
|
<li><code>println!</code>: same as <code>print!</code> but a newline is appended.</li>
|
||||||
|
<li><code>eprint!</code>: same as <code>format!</code> but the text is printed to the standard error (io::stderr).</li>
|
||||||
|
<li><code>eprintln!</code>: same as <code>eprint!</code>but a newline is appended.</li>
|
||||||
|
</ul>
|
||||||
|
<p>All parse text in the same fashion. As a plus, Rust checks format correctness at compile time.</p>
|
||||||
|
<h2 id="format"><a class="header" href="#format"><code>format!</code></a></h2>
|
||||||
|
<p>1.🌟</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let s1 = "hello";
|
||||||
|
/* Fill in the blank */
|
||||||
|
let s = format!(__);
|
||||||
|
assert_eq!(s, "hello, world!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="print-println"><a class="header" href="#print-println"><code>print!</code>, <code>println!</code></a></h2>
|
||||||
|
<p>2.🌟</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
/* Fill in the blanks to make it print:
|
||||||
|
Hello world, I am
|
||||||
|
Sunface!
|
||||||
|
*/
|
||||||
|
__("hello world, ");
|
||||||
|
__("I am");
|
||||||
|
__("Sunface!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/formatted-output/println.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../formatted-output/intro.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="../formatted-output/debug-display.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="../formatted-output/intro.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="../formatted-output/debug-display.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
604
functional-programing/closure.html
Normal file
604
functional-programing/closure.html
Normal file
@ -0,0 +1,604 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Closure - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/functional-programing/closure.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="closure"><a class="header" href="#closure">Closure</a></h1>
|
||||||
|
<p>Closures can capture the enclosing environments. For example we can capture the <code>x</code> variable :</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
let x = 1;
|
||||||
|
let closure = |val| val + x;
|
||||||
|
assert_eq!(closure(2), 3);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>From the syntax, we can see that closures are very convenient for on the fly usage. Unlike functions, both the input and return types of a closure can be inferred by the compiler.</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
// Increment via closures and functions.
|
||||||
|
fn function(i: i32) -> i32 { i + 1 }
|
||||||
|
|
||||||
|
// Closures are anonymous, here we are binding them to references
|
||||||
|
//
|
||||||
|
// These nameless functions are assigned to appropriately named variables.
|
||||||
|
let closure_annotated = |i: i32| -> i32 { i + 1 };
|
||||||
|
let closure_inferred = |i | i + 1 ;
|
||||||
|
|
||||||
|
let i = 1;
|
||||||
|
// Call the function and closures.
|
||||||
|
println!("function: {}", function(i));
|
||||||
|
println!("closure_annotated: {}", closure_annotated(i));
|
||||||
|
println!("closure_inferred: {}", closure_inferred(i));
|
||||||
|
|
||||||
|
// A closure taking no arguments which returns an `i32`.
|
||||||
|
// The return type is inferred.
|
||||||
|
let one = || 1;
|
||||||
|
println!("closure returning one: {}", one());
|
||||||
|
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="capturing"><a class="header" href="#capturing">Capturing</a></h2>
|
||||||
|
<p>Closures can capture variables by borrowing or moving. But they prefer to capture by borrowing and only go lower when required:</p>
|
||||||
|
<ul>
|
||||||
|
<li>By reference: <code>&T</code></li>
|
||||||
|
<li>By mutable reference: <code>&mut T</code></li>
|
||||||
|
<li>By value: <code>T</code></li>
|
||||||
|
</ul>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work with least amount of changes*/
|
||||||
|
fn main() {
|
||||||
|
let color = String::from("green");
|
||||||
|
|
||||||
|
let print = move || println!("`color`: {}", color);
|
||||||
|
|
||||||
|
print();
|
||||||
|
print();
|
||||||
|
|
||||||
|
// `color` can be borrowed immutably again, because the closure only holds
|
||||||
|
// an immutable reference to `color`.
|
||||||
|
let _reborrow = &color;
|
||||||
|
|
||||||
|
println!("{}",color);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work
|
||||||
|
- Dont use `_reborrow` and `_count_reborrowed`
|
||||||
|
- Dont modify `assert_eq`
|
||||||
|
*/
|
||||||
|
fn main() {
|
||||||
|
let mut count = 0;
|
||||||
|
|
||||||
|
let mut inc = || {
|
||||||
|
count += 1;
|
||||||
|
println!("`count`: {}", count);
|
||||||
|
};
|
||||||
|
|
||||||
|
inc();
|
||||||
|
|
||||||
|
|
||||||
|
let _reborrow = &count;
|
||||||
|
|
||||||
|
inc();
|
||||||
|
|
||||||
|
// The closure no longer needs to borrow `&mut count`. Therefore, it is
|
||||||
|
// possible to reborrow without an error
|
||||||
|
let _count_reborrowed = &mut count;
|
||||||
|
|
||||||
|
assert_eq!(count, 0);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work in two ways, none of them is to remove `take(movable)` away from the code
|
||||||
|
*/
|
||||||
|
fn main() {
|
||||||
|
let movable = Box::new(3);
|
||||||
|
|
||||||
|
let consume = || {
|
||||||
|
println!("`movable`: {:?}", movable);
|
||||||
|
take(movable);
|
||||||
|
};
|
||||||
|
|
||||||
|
consume();
|
||||||
|
consume();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn take<T>(_v: T) {}</code></pre></pre>
|
||||||
|
<p>For comparison, the following code has no error:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
let movable = Box::new(3);
|
||||||
|
|
||||||
|
let consume = move || {
|
||||||
|
println!("`movable`: {:?}", movable);
|
||||||
|
};
|
||||||
|
|
||||||
|
consume();
|
||||||
|
consume();
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="type-inferred"><a class="header" href="#type-inferred">Type inferred</a></h2>
|
||||||
|
<p>The following four closures has no difference in input and return types.</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>fn add_one_v1 (x: u32) -> u32 { x + 1 }
|
||||||
|
let add_one_v2 = |x: u32| -> u32 { x + 1 };
|
||||||
|
let add_one_v3 = |x| { x + 1 };
|
||||||
|
let add_one_v4 = |x| x + 1 ;
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
let example_closure = |x| x;
|
||||||
|
|
||||||
|
let s = example_closure(String::from("hello"));
|
||||||
|
|
||||||
|
/* Make it work, only change the following line */
|
||||||
|
let n = example_closure(5);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="fn-fnmut-fnonce"><a class="header" href="#fn-fnmut-fnonce">Fn, FnMut, FnOnce</a></h2>
|
||||||
|
<p>When taking a closure as an input parameter, the closure's complete type must be annotated using one of the following traits:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Fn: the closure uses the captured value by reference (&T)</li>
|
||||||
|
<li>FnMut: the closure uses the captured value by mutable reference (&mut T)</li>
|
||||||
|
<li>FnOnce: the closure uses the captured value by value (T)</li>
|
||||||
|
</ul>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work by changing the trait bound, in two ways*/
|
||||||
|
fn fn_once<F>(func: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(usize) -> bool,
|
||||||
|
{
|
||||||
|
println!("{}", func(3));
|
||||||
|
println!("{}", func(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = vec![1, 2, 3];
|
||||||
|
fn_once(|z|{z == x.len()})
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
let mut s = String::new();
|
||||||
|
|
||||||
|
let update_string = |str| s.push_str(str);
|
||||||
|
|
||||||
|
exec(update_string);
|
||||||
|
|
||||||
|
println!("{:?}",s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in the blank */
|
||||||
|
fn exec<'a, F: __>(mut f: F) {
|
||||||
|
f("hello")
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="which-trait-does-the-compiler-prefer-to-use"><a class="header" href="#which-trait-does-the-compiler-prefer-to-use">Which trait does the compiler prefer to use?</a></h4>
|
||||||
|
<ul>
|
||||||
|
<li>Fn: the closure uses the captured value by reference (&T)</li>
|
||||||
|
<li>FnMut: the closure uses the captured value by mutable reference (&mut T)</li>
|
||||||
|
<li>FnOnce: the closure uses the captured value by value (T)</li>
|
||||||
|
</ul>
|
||||||
|
<p>On a variable-by-variable basis, the compiler will capture variables in the least restrictive manner possible.</p>
|
||||||
|
<p>For instance, consider a parameter annotated as FnOnce. This specifies that the closure may capture by <code>&T</code>, <code>&mut T</code>, or <code>T</code>, but the compiler will ultimately choose based on how the captured variables are used in the closure.
|
||||||
|
Which trait to use is determined by what the closure does with captured value.</p>
|
||||||
|
<p>This is because if a move is possible, then any type of borrow should also be possible. Note that the reverse is not true. If the parameter is annotated as <code>Fn</code>, then capturing variables by <code>&mut T</code> or <code>T</code> are not allowed.</p>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blank */
|
||||||
|
|
||||||
|
// A function which takes a closure as an argument and calls it.
|
||||||
|
// <F> denotes that F is a "Generic type parameter"
|
||||||
|
fn apply<F>(f: F) where
|
||||||
|
// The closure takes no input and returns nothing.
|
||||||
|
F: __ {
|
||||||
|
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A function which takes a closure and returns an `i32`.
|
||||||
|
fn apply_to_3<F>(f: F) -> i32 where
|
||||||
|
// The closure takes an `i32` and returns an `i32`.
|
||||||
|
F: Fn(i32) -> i32 {
|
||||||
|
|
||||||
|
f(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
let greeting = "hello";
|
||||||
|
// A non-copy type.
|
||||||
|
// `to_owned` creates owned data from borrowed one
|
||||||
|
let mut farewell = "goodbye".to_owned();
|
||||||
|
|
||||||
|
// Capture 2 variables: `greeting` by reference and
|
||||||
|
// `farewell` by value.
|
||||||
|
let diary = || {
|
||||||
|
// `greeting` is by reference: requires `Fn`.
|
||||||
|
println!("I said {}.", greeting);
|
||||||
|
|
||||||
|
// Mutation forces `farewell` to be captured by
|
||||||
|
// mutable reference. Now requires `FnMut`.
|
||||||
|
farewell.push_str("!!!");
|
||||||
|
println!("Then I screamed {}.", farewell);
|
||||||
|
println!("Now I can sleep. zzzzz");
|
||||||
|
|
||||||
|
// Manually calling drop forces `farewell` to
|
||||||
|
// be captured by value. Now requires `FnOnce`.
|
||||||
|
mem::drop(farewell);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Call the function which applies the closure.
|
||||||
|
apply(diary);
|
||||||
|
|
||||||
|
// `double` satisfies `apply_to_3`'s trait bound
|
||||||
|
let double = |x| 2 * x;
|
||||||
|
|
||||||
|
println!("3 doubled: {}", apply_to_3(double));
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>Move closures may still implement <code>Fn</code> or <code>FnMut</code>, even though they capture variables by move. This is because the traits implemented by a closure type are determined by what the closure does with captured values, not how it captures them. The <code>move</code> keyword only specifies the latter.</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
let s = String::new();
|
||||||
|
|
||||||
|
let update_string = move || println!("{}",s);
|
||||||
|
|
||||||
|
exec(update_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec<F: FnOnce()>(f: F) {
|
||||||
|
f()
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>The following code also has no error:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
let s = String::new();
|
||||||
|
|
||||||
|
let update_string = move || println!("{}",s);
|
||||||
|
|
||||||
|
exec(update_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec<F: Fn()>(f: F) {
|
||||||
|
f()
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blank */
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::new();
|
||||||
|
|
||||||
|
let update_string = |str| -> String {s.push_str(str); s };
|
||||||
|
|
||||||
|
exec(update_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn exec<'a, F: __>(mut f: F) {
|
||||||
|
f("hello");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="input-functions"><a class="header" href="#input-functions">Input functions</a></h2>
|
||||||
|
<p>Since closure can be used as arguments, you might wonder can we use functions as arguments too? And indeed we can.</p>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
/* Implement `call_me` to make it work */
|
||||||
|
fn call_me {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn function() {
|
||||||
|
println!("I'm a function!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let closure = || println!("I'm a closure!");
|
||||||
|
|
||||||
|
call_me(closure);
|
||||||
|
call_me(function);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="closure-as-return-types"><a class="header" href="#closure-as-return-types">Closure as return types</a></h2>
|
||||||
|
<p>Returning a closure is much harder than you may have thought of.</p>
|
||||||
|
<ol start="10">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blank using two approaches,
|
||||||
|
and fix the error */
|
||||||
|
fn create_fn() -> __ {
|
||||||
|
let num = 5;
|
||||||
|
|
||||||
|
// How does the following closure capture the environment variable `num`
|
||||||
|
// &T, &mut T, T ?
|
||||||
|
|x| x + num
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let fn_plain = create_fn();
|
||||||
|
fn_plain(1);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="11">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blank and fix the error*/
|
||||||
|
fn factory(x:i32) -> __ {
|
||||||
|
|
||||||
|
let num = 5;
|
||||||
|
|
||||||
|
if x > 1{
|
||||||
|
move |x| x + num
|
||||||
|
} else {
|
||||||
|
move |x| x + num
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="closure-in-structs"><a class="header" href="#closure-in-structs">Closure in structs</a></h2>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">struct Cacher<T,E>
|
||||||
|
where
|
||||||
|
T: Fn(E) -> E,
|
||||||
|
E: Copy
|
||||||
|
{
|
||||||
|
query: T,
|
||||||
|
value: Option<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T,E> Cacher<T,E>
|
||||||
|
where
|
||||||
|
T: Fn(E) -> E,
|
||||||
|
E: Copy
|
||||||
|
{
|
||||||
|
fn new(query: T) -> Cacher<T,E> {
|
||||||
|
Cacher {
|
||||||
|
query,
|
||||||
|
value: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value(&mut self, arg: E) -> E {
|
||||||
|
match self.value {
|
||||||
|
Some(v) => v,
|
||||||
|
None => {
|
||||||
|
let v = (self.query)(arg);
|
||||||
|
self.value = Some(v);
|
||||||
|
v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn call_with_different_values() {
|
||||||
|
let mut c = Cacher::new(|a| a);
|
||||||
|
|
||||||
|
let v1 = c.value(1);
|
||||||
|
let v2 = c.value(2);
|
||||||
|
|
||||||
|
assert_eq!(v2, 1);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/functional-programing/closure.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../functional-programing/intro.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="../functional-programing/iterator.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="../functional-programing/intro.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="../functional-programing/iterator.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
229
functional-programing/intro.html
Normal file
229
functional-programing/intro.html
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Functional programing - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/functional-programing/intro.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="functional-programing"><a class="header" href="#functional-programing">Functional programing</a></h1>
|
||||||
|
<p>Learning resources:</p>
|
||||||
|
<ul>
|
||||||
|
<li>English: <a href="https://doc.rust-lang.org/book/ch13-00-functional-features.html">Rust Book 13</a></li>
|
||||||
|
<li>简体中文: <a href="https://course.rs/advance/functional-programing/intro.html">Rust语言圣经 - 函数式编程:闭包和迭代器</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../lifetime/advance.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="../functional-programing/closure.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="../lifetime/advance.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="../functional-programing/closure.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
520
functional-programing/iterator.html
Normal file
520
functional-programing/iterator.html
Normal file
@ -0,0 +1,520 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Iterator - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/functional-programing/iterator.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="iterator"><a class="header" href="#iterator">Iterator</a></h1>
|
||||||
|
<p>The iterator pattern allows us to perform some tasks on a sequence of items in turn. An iterator is responsible for the logic of iterating over each item and determining when the sequence has finished.</p>
|
||||||
|
<h2 id="for-and-iterator"><a class="header" href="#for-and-iterator">for and iterator</a></h2>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
let v = vec![1, 2, 3];
|
||||||
|
for x in v {
|
||||||
|
println!("{}",x)
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>In the code above, You may consider <code>for</code> as a simple loop, but actually it is iterating over a iterator.</p>
|
||||||
|
<p>By default <code>for</code> will apply the <code>into_iter</code> to the collection, and change it into a iterator. As a result, the following code is equivalent to previous one:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
let v = vec![1, 2, 3];
|
||||||
|
for x in v.into_iter() {
|
||||||
|
println!("{}",x)
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Refactoring the following code using iterators */
|
||||||
|
fn main() {
|
||||||
|
let arr = [0; 10];
|
||||||
|
for i in 0..arr.len() {
|
||||||
|
println!("{}",arr[i]);
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟 One of the easiest ways to create an iterator is to use the range notion: <code>a..b</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blank */
|
||||||
|
fn main() {
|
||||||
|
let mut v = Vec::new();
|
||||||
|
for n in __ {
|
||||||
|
v.push(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(v.len(), 100);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="next-method"><a class="header" href="#next-method">next method</a></h2>
|
||||||
|
<p>All iterators implement a trait named <code>Iterator</code> that is defined in the standard library:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>pub trait Iterator {
|
||||||
|
type Item;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item>;
|
||||||
|
|
||||||
|
// Methods with default implementations elided
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>And we can call the <code>next</code> method on iterators directly.</p>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill the blanks and fix the errors.
|
||||||
|
Using two ways if possible */
|
||||||
|
fn main() {
|
||||||
|
let v1 = vec![1, 2];
|
||||||
|
|
||||||
|
assert_eq!(v1.next(), __);
|
||||||
|
assert_eq!(v1.next(), __);
|
||||||
|
assert_eq!(v1.next(), __);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="into_iter-iter-and-iter_mut"><a class="header" href="#into_iter-iter-and-iter_mut">into_iter, iter and iter_mut</a></h2>
|
||||||
|
<p>In the previous section, we have mentioned that <code>for</code> will apply the <code>into_iter</code> to the collection, and change it into a iterator. However, this is not the only way to convert collections into iterators.</p>
|
||||||
|
<p><code>into_iter</code>, <code>iter</code>, <code>iter_mut</code>, all of them can convert a collection into iterator, but in different ways.</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>into_iter</code> consumes the collection, once the collection has been consumed, it is no longer available for reuse, because its ownership has been moved within the loop.</li>
|
||||||
|
<li><code>iter</code>, this borrows each element of the collection through each iteration, thus leaving the collection untouched and available for reuse after the loop</li>
|
||||||
|
<li><code>iter_mut</code>, this mutably borrows each element of the collection, allowing for the collection to be modified in place.</li>
|
||||||
|
</ul>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work */
|
||||||
|
fn main() {
|
||||||
|
let arr = vec![0; 10];
|
||||||
|
for i in arr {
|
||||||
|
println!("{}", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{:?}",arr);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blank */
|
||||||
|
fn main() {
|
||||||
|
let mut names = vec!["Bob", "Frank", "Ferris"];
|
||||||
|
|
||||||
|
for name in names.__{
|
||||||
|
*name = match name {
|
||||||
|
&mut "Ferris" => "There is a rustacean among us!",
|
||||||
|
_ => "Hello",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("names: {:?}", names);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blank */
|
||||||
|
fn main() {
|
||||||
|
let mut values = vec![1, 2, 3];
|
||||||
|
let mut values_iter = values.__;
|
||||||
|
|
||||||
|
if let Some(v) = values_iter.__{
|
||||||
|
__
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(values, vec![0, 2, 3]);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="creating-our-own-iterator"><a class="header" href="#creating-our-own-iterator">Creating our own iterator</a></h2>
|
||||||
|
<p>We can not only create iterators from collection's types, but also can create iterators by implementing the <code>Iterator</code> trait on our own types.</p>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">struct Counter {
|
||||||
|
count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Counter {
|
||||||
|
fn new() -> Counter {
|
||||||
|
Counter { count: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for Counter {
|
||||||
|
type Item = u32;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.count < 5 {
|
||||||
|
self.count += 1;
|
||||||
|
Some(self.count)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut counter = Counter::new();
|
||||||
|
|
||||||
|
assert_eq!(counter.next(), Some(1));
|
||||||
|
assert_eq!(counter.next(), Some(2));
|
||||||
|
assert_eq!(counter.next(), Some(3));
|
||||||
|
assert_eq!(counter.next(), Some(4));
|
||||||
|
assert_eq!(counter.next(), Some(5));
|
||||||
|
assert_eq!(counter.next(), None);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">struct Fibonacci {
|
||||||
|
curr: u32,
|
||||||
|
next: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement `Iterator` for `Fibonacci`.
|
||||||
|
// The `Iterator` trait only requires a method to be defined for the `next` element.
|
||||||
|
impl Iterator for Fibonacci {
|
||||||
|
// We can refer to this type using Self::Item
|
||||||
|
type Item = u32;
|
||||||
|
|
||||||
|
/* Implement next method */
|
||||||
|
fn next(&mut self)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a Fibonacci sequence generator
|
||||||
|
fn fibonacci() -> Fibonacci {
|
||||||
|
Fibonacci { curr: 0, next: 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut fib = fibonacci();
|
||||||
|
assert_eq!(fib.next(), Some(1));
|
||||||
|
assert_eq!(fib.next(), Some(1));
|
||||||
|
assert_eq!(fib.next(), Some(2));
|
||||||
|
assert_eq!(fib.next(), Some(3));
|
||||||
|
assert_eq!(fib.next(), Some(5));
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="methods-that-consume-the-iterator"><a class="header" href="#methods-that-consume-the-iterator">Methods that Consume the Iterator</a></h2>
|
||||||
|
<p>The <code>Iterator</code> trait has a number of methods with default implementations provided by the standard library.</p>
|
||||||
|
<h3 id="consuming-adaptors"><a class="header" href="#consuming-adaptors">Consuming adaptors</a></h3>
|
||||||
|
<p>Some of these methods call the method <code>next</code>to use up the iterator, so they are called <em>consuming adaptors</em>.</p>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
/* Fill in the blank and fix the errors */
|
||||||
|
fn main() {
|
||||||
|
let v1 = vec![1, 2, 3];
|
||||||
|
|
||||||
|
let v1_iter = v1.iter();
|
||||||
|
|
||||||
|
// The sum method will take the ownership of the iterator and iterates through the items by repeatedly calling next method
|
||||||
|
let total = v1_iter.sum();
|
||||||
|
|
||||||
|
assert_eq!(total, __);
|
||||||
|
|
||||||
|
println!("{:?}, {:?}",v1, v1_iter);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="collect"><a class="header" href="#collect">Collect</a></h4>
|
||||||
|
<p>Other than converting a collection into an iterator, we can also <code>collect</code> the result values into a collection, <code>collect</code> will consume the iterator.</p>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work */
|
||||||
|
use std::collections::HashMap;
|
||||||
|
fn main() {
|
||||||
|
let names = [("sunface",18), ("sunfei",18)];
|
||||||
|
let folks: HashMap<_, _> = names.into_iter().collect();
|
||||||
|
|
||||||
|
println!("{:?}",folks);
|
||||||
|
|
||||||
|
let v1: Vec<i32> = vec![1, 2, 3];
|
||||||
|
|
||||||
|
let v2 = v1.iter().collect();
|
||||||
|
|
||||||
|
assert_eq!(v2, vec![1, 2, 3]);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="iterator-adaptors"><a class="header" href="#iterator-adaptors">Iterator adaptors</a></h3>
|
||||||
|
<p>Methods allowing you to change one iterator into another iterator are known as <em>iterator adaptors</em>. You can chain multiple iterator adaptors to perform complex actions in a readable way.</p>
|
||||||
|
<p>But because <strong>all iterators are lazy</strong>, you have to call one of the consuming adapters to get results from calls to iterator adapters.</p>
|
||||||
|
<ol start="10">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blanks */
|
||||||
|
fn main() {
|
||||||
|
let v1: Vec<i32> = vec![1, 2, 3];
|
||||||
|
|
||||||
|
let v2: Vec<_> = v1.iter().__.__;
|
||||||
|
|
||||||
|
assert_eq!(v2, vec![2, 3, 4]);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="11">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blanks */
|
||||||
|
use std::collections::HashMap;
|
||||||
|
fn main() {
|
||||||
|
let names = ["sunface", "sunfei"];
|
||||||
|
let ages = [18, 18];
|
||||||
|
let folks: HashMap<_, _> = names.into_iter().__.collect();
|
||||||
|
|
||||||
|
println!("{:?}",folks);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="using-closures-in-iterator-adaptors"><a class="header" href="#using-closures-in-iterator-adaptors">Using closures in iterator adaptors</a></h4>
|
||||||
|
<ol start="12">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Fill in the blanks */
|
||||||
|
#[derive(PartialEq, Debug)]
|
||||||
|
struct Shoe {
|
||||||
|
size: u32,
|
||||||
|
style: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shoes_in_size(shoes: Vec<Shoe>, shoe_size: u32) -> Vec<Shoe> {
|
||||||
|
shoes.into_iter().__.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let shoes = vec![
|
||||||
|
Shoe {
|
||||||
|
size: 10,
|
||||||
|
style: String::from("sneaker"),
|
||||||
|
},
|
||||||
|
Shoe {
|
||||||
|
size: 13,
|
||||||
|
style: String::from("sandal"),
|
||||||
|
},
|
||||||
|
Shoe {
|
||||||
|
size: 10,
|
||||||
|
style: String::from("boot"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
let in_my_size = shoes_in_size(shoes, 10);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
in_my_size,
|
||||||
|
vec![
|
||||||
|
Shoe {
|
||||||
|
size: 10,
|
||||||
|
style: String::from("sneaker")
|
||||||
|
},
|
||||||
|
Shoe {
|
||||||
|
size: 10,
|
||||||
|
style: String::from("boot")
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/functional-programing/iterator.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../functional-programing/closure.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="../newtype-sized.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="../functional-programing/closure.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="../newtype-sized.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
487
generics-traits/advanced-traits.html
Normal file
487
generics-traits/advanced-traits.html
Normal file
@ -0,0 +1,487 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Advanced Traits - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/generics-traits/advanced-traits.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="advance-traits"><a class="header" href="#advance-traits">Advance Traits</a></h1>
|
||||||
|
<h2 id="associated-types"><a class="header" href="#associated-types">Associated types</a></h2>
|
||||||
|
<p>The use of "Associated types" improves the overall readability of code by moving inner types locally into a trait as output types. For example :</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>pub trait CacheableItem: Clone + Default + fmt::Debug + Decodable + Encodable {
|
||||||
|
type Address: AsRef<[u8]> + Clone + fmt::Debug + Eq + Hash;
|
||||||
|
fn is_null(&self) -> bool;
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>Using of <code>Address</code> is much more clearer and convenient than <code>AsRef<[u8]> + Clone + fmt::Debug + Eq + Hash</code>.</p>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
struct Container(i32, i32);
|
||||||
|
|
||||||
|
// USING associated types to re-implement trait Contains.
|
||||||
|
// trait Contains {
|
||||||
|
// type A;
|
||||||
|
// type B;
|
||||||
|
|
||||||
|
trait Contains<A, B> {
|
||||||
|
fn contains(&self, _: &A, _: &B) -> bool;
|
||||||
|
fn first(&self) -> i32;
|
||||||
|
fn last(&self) -> i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Contains<i32, i32> for Container {
|
||||||
|
fn contains(&self, number_1: &i32, number_2: &i32) -> bool {
|
||||||
|
(&self.0 == number_1) && (&self.1 == number_2)
|
||||||
|
}
|
||||||
|
// Grab the first number.
|
||||||
|
fn first(&self) -> i32 { self.0 }
|
||||||
|
|
||||||
|
// Grab the last number.
|
||||||
|
fn last(&self) -> i32 { self.1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn difference<A, B, C: Contains<A, B>>(container: &C) -> i32 {
|
||||||
|
container.last() - container.first()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let number_1 = 3;
|
||||||
|
let number_2 = 10;
|
||||||
|
|
||||||
|
let container = Container(number_1, number_2);
|
||||||
|
|
||||||
|
println!("Does container contain {} and {}: {}",
|
||||||
|
&number_1, &number_2,
|
||||||
|
container.contains(&number_1, &number_2));
|
||||||
|
println!("First number: {}", container.first());
|
||||||
|
println!("Last number: {}", container.last());
|
||||||
|
|
||||||
|
println!("The difference is: {}", difference(&container));
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="default-generic-type-parameters"><a class="header" href="#default-generic-type-parameters">Default Generic Type Parameters</a></h2>
|
||||||
|
<p>When we use generic type parameters, we can specify a default concrete type for the generic type. This eliminates the need for implementors of the trait to specify a concrete type if the default type works.</p>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
use std::ops::Sub;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
struct Point<T> {
|
||||||
|
x: T,
|
||||||
|
y: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILL in the blank in three ways: two of them use the default generic parameters, the other one not.
|
||||||
|
// Notice that the implementation uses the associated type `Output`.
|
||||||
|
impl __ {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn sub(self, other: Self) -> Self::Output {
|
||||||
|
Point {
|
||||||
|
x: self.x - other.x,
|
||||||
|
y: self.y - other.y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(Point { x: 2, y: 3 } - Point { x: 1, y: 0 },
|
||||||
|
Point { x: 1, y: 3 });
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="fully-qualified-syntax"><a class="header" href="#fully-qualified-syntax">Fully Qualified Syntax</a></h2>
|
||||||
|
<p>Nothing in Rust prevents a trait from having a method with the same name as another trait’s method, nor does Rust prevent you from implementing both traits on one type. It’s also possible to implement a method directly on the type with the same name as methods from traits.</p>
|
||||||
|
<p>When calling methods with the same name, we have to use Fully Qualified Syntax.</p>
|
||||||
|
<h4 id="example"><a class="header" href="#example">Example</a></h4>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">trait UsernameWidget {
|
||||||
|
// Get the selected username out of this widget
|
||||||
|
fn get(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait AgeWidget {
|
||||||
|
// Get the selected age out of this widget
|
||||||
|
fn get(&self) -> u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A form with both a UsernameWidget and an AgeWidget.
|
||||||
|
struct Form {
|
||||||
|
username: String,
|
||||||
|
age: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UsernameWidget for Form {
|
||||||
|
fn get(&self) -> String {
|
||||||
|
self.username.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AgeWidget for Form {
|
||||||
|
fn get(&self) -> u8 {
|
||||||
|
self.age
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let form = Form{
|
||||||
|
username: "rustacean".to_owned(),
|
||||||
|
age: 28,
|
||||||
|
};
|
||||||
|
|
||||||
|
// If you uncomment this line, you'll get an error saying
|
||||||
|
// "multiple `get` found". Because, after all, there are multiple methods
|
||||||
|
// named `get`.
|
||||||
|
// println!("{}", form.get());
|
||||||
|
|
||||||
|
let username = UsernameWidget::get(&form);
|
||||||
|
assert_eq!("rustacean".to_owned(), username);
|
||||||
|
let age = AgeWidget::get(&form); // You can also use `<Form as AgeWidget>::get`
|
||||||
|
assert_eq!(28, age);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="exercise"><a class="header" href="#exercise">Exercise</a></h4>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">trait Pilot {
|
||||||
|
fn fly(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Wizard {
|
||||||
|
fn fly(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Human;
|
||||||
|
|
||||||
|
impl Pilot for Human {
|
||||||
|
fn fly(&self) -> String {
|
||||||
|
String::from("This is your captain speaking.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Wizard for Human {
|
||||||
|
fn fly(&self) -> String {
|
||||||
|
String::from("Up!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Human {
|
||||||
|
fn fly(&self) -> String {
|
||||||
|
String::from("*waving arms furiously*")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let person = Human;
|
||||||
|
|
||||||
|
assert_eq!(__, "This is your captain speaking.");
|
||||||
|
assert_eq!(__, "Up!");
|
||||||
|
|
||||||
|
assert_eq!(__, "*waving arms furiously*");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="supertraits"><a class="header" href="#supertraits">Supertraits</a></h2>
|
||||||
|
<p>Sometimes, you might need one trait to use another trait’s functionality( like the "inheritance" in other languages ). In this case, you need to rely on the dependent trait also being implemented. The trait you rely on is a <code>supertrait</code> of the trait you’re implementing.</p>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
trait Person {
|
||||||
|
fn name(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Person is a supertrait of Student.
|
||||||
|
// Implementing Student requires you to also impl Person.
|
||||||
|
trait Student: Person {
|
||||||
|
fn university(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Programmer {
|
||||||
|
fn fav_language(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompSciStudent (computer science student) is a subtrait of both Programmer
|
||||||
|
// and Student. Implementing CompSciStudent requires you to impl both supertraits.
|
||||||
|
trait CompSciStudent: Programmer + Student {
|
||||||
|
fn git_username(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn comp_sci_student_greeting(student: &dyn CompSciStudent) -> String {
|
||||||
|
format!(
|
||||||
|
"My name is {} and I attend {}. My favorite language is {}. My Git username is {}",
|
||||||
|
student.name(),
|
||||||
|
student.university(),
|
||||||
|
student.fav_language(),
|
||||||
|
student.git_username()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CSStudent {
|
||||||
|
name: String,
|
||||||
|
university: String,
|
||||||
|
fav_language: String,
|
||||||
|
git_username: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMPLEMENT the necessary traits for CSStudent to make the code work
|
||||||
|
impl ...
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let student = CSStudent {
|
||||||
|
name: "Sunfei".to_string(),
|
||||||
|
university: "XXX".to_string(),
|
||||||
|
fav_language: "Rust".to_string(),
|
||||||
|
git_username: "sunface".to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
// FILL in the blank
|
||||||
|
println!("{}", comp_sci_student_greeting(__));
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="orphan-rules"><a class="header" href="#orphan-rules">Orphan Rules</a></h2>
|
||||||
|
<p>We can’t implement external traits on external types. For example, we can’t implement the <code>Display</code> trait on <code>Vec<T></code> within our own crate, because <code>Display</code> and <code>Vec<T></code> are defined in the standard library and aren’t local to our crate.</p>
|
||||||
|
<p>This restriction is often called the orphan rule, so named because the parent type is not present. This rule ensures that other people’s code can’t break your code and vice versa.</p>
|
||||||
|
<p>It’s possible to get around this restriction using the newtype pattern, which involves creating a new type in a tuple struct.</p>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::fmt;
|
||||||
|
|
||||||
|
// DEFINE a newtype `Pretty` here
|
||||||
|
|
||||||
|
|
||||||
|
impl fmt::Display for Pretty {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "\"{}\"", self.0.clone() + ", world")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let w = Pretty("hello".to_string());
|
||||||
|
println!("w = {}", w);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../generics-traits/trait-object.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="../collections/intro.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="../generics-traits/trait-object.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="../collections/intro.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
359
generics-traits/const-generics.html
Normal file
359
generics-traits/const-generics.html
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Const Generics - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/generics-traits/const-generics.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="const-generics"><a class="header" href="#const-generics">Const Generics</a></h1>
|
||||||
|
<p>Const generics are generic arguments that range over constant values, rather than types or lifetimes. This allows, for instance, types to be parameterized by integers. In fact, there has been one example of const generic types since early on in Rust's development: the array types [T; N], for some type T and N: usize. However, there has previously been no way to abstract over arrays of an arbitrary size: if you wanted to implement a trait for arrays of any size, you would have to do so manually for each possible value. For a long time, even the standard library methods for arrays were limited to arrays of length at most 32 due to this problem.</p>
|
||||||
|
<h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
|
||||||
|
<ol>
|
||||||
|
<li>Here's an example of a type and implementation making use of const generics: a type wrapping a pair of arrays of the same size.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">struct ArrayPair<T, const N: usize> {
|
||||||
|
left: [T; N],
|
||||||
|
right: [T; N],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Debug, const N: usize> Debug for ArrayPair<T, N> {
|
||||||
|
// ...
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>Currently, const parameters may only be instantiated by const arguments of the following forms:</li>
|
||||||
|
</ol>
|
||||||
|
<ul>
|
||||||
|
<li>A standalone const parameter.</li>
|
||||||
|
<li>A literal (i.e. an integer, bool, or character).</li>
|
||||||
|
<li>A concrete constant expression (enclosed by {}), involving no generic parameters.</li>
|
||||||
|
</ul>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn foo<const N: usize>() {}
|
||||||
|
|
||||||
|
fn bar<T, const M: usize>() {
|
||||||
|
foo::<M>(); // Okay: `M` is a const parameter
|
||||||
|
foo::<2021>(); // Okay: `2021` is a literal
|
||||||
|
foo::<{20 * 100 + 20 * 10 + 1}>(); // Okay: const expression contains no generic parameters
|
||||||
|
|
||||||
|
foo::<{ M + 1 }>(); // Error: const expression contains the generic parameter `M`
|
||||||
|
foo::<{ std::mem::size_of::<T>() }>(); // Error: const expression contains the generic parameter `T`
|
||||||
|
|
||||||
|
let _: [u8; M]; // Okay: `M` is a const parameter
|
||||||
|
let _: [u8; std::mem::size_of::<T>()]; // Error: const expression contains the generic parameter `T`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>Const generics can also let us avoid some runtime checks.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">/// A region of memory containing at least `N` `T`s.
|
||||||
|
pub struct MinSlice<T, const N: usize> {
|
||||||
|
/// The bounded region of memory. Exactly `N` `T`s.
|
||||||
|
pub head: [T; N],
|
||||||
|
/// Zero or more remaining `T`s after the `N` in the bounded region.
|
||||||
|
pub tail: [T],
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let slice: &[u8] = b"Hello, world";
|
||||||
|
let reference: Option<&u8> = slice.get(6);
|
||||||
|
// We know this value is `Some(b' ')`,
|
||||||
|
// but the compiler can't know that.
|
||||||
|
assert!(reference.is_some());
|
||||||
|
|
||||||
|
let slice: &[u8] = b"Hello, world";
|
||||||
|
// Length check is performed when we construct a MinSlice,
|
||||||
|
// and it's known at compile time to be of length 12.
|
||||||
|
// If the `unwrap()` succeeds, no more checks are needed
|
||||||
|
// throughout the `MinSlice`'s lifetime.
|
||||||
|
let minslice = MinSlice::<u8, 12>::from_slice(slice).unwrap();
|
||||||
|
let value: u8 = minslice.head[6];
|
||||||
|
assert_eq!(value, b' ')
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="exercises"><a class="header" href="#exercises">Exercises</a></h2>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟 <code><T, const N: usize></code> is part of the struct type, it means <code>Array<i32, 3></code> and <code>Array<i32, 4></code> are different types.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">struct Array<T, const N: usize> {
|
||||||
|
data : [T; N]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let arrays = [
|
||||||
|
Array{
|
||||||
|
data: [1, 2, 3],
|
||||||
|
},
|
||||||
|
Array {
|
||||||
|
data: [1.0, 2.0, 3.0],
|
||||||
|
},
|
||||||
|
Array {
|
||||||
|
data: [1, 2]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blanks to make it work.
|
||||||
|
fn print_array<__>(__) {
|
||||||
|
println!("{:?}", arr);
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let arr = [1, 2, 3];
|
||||||
|
print_array(arr);
|
||||||
|
|
||||||
|
let arr = ["hello", "world"];
|
||||||
|
print_array(arr);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟🌟 Sometimes we want to limit the size of a variable, e.g when using in embedding environments, then <code>const expressions</code> will fit your needs.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">#![allow(incomplete_features)]
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
|
||||||
|
fn check_size<T>(val: T)
|
||||||
|
where
|
||||||
|
Assert<{ core::mem::size_of::<T>() < 768 }>: IsTrue,
|
||||||
|
{
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix the errors in main.
|
||||||
|
fn main() {
|
||||||
|
check_size([0u8; 767]);
|
||||||
|
check_size([0i32; 191]);
|
||||||
|
check_size(["hello你好"; __]); // Size of &str ?
|
||||||
|
check_size([(); __].map(|_| "hello你好".to_string())); // Size of String?
|
||||||
|
check_size(['中'; __]); // Size of char ?
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub enum Assert<const CHECK: bool> {}
|
||||||
|
|
||||||
|
pub trait IsTrue {}
|
||||||
|
|
||||||
|
impl IsTrue for Assert<true> {}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/const-generics.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../generics-traits/generics.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="../generics-traits/traits.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="../generics-traits/generics.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="../generics-traits/traits.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
369
generics-traits/generics.html
Normal file
369
generics-traits/generics.html
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Generics - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/generics-traits/generics.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="generics"><a class="header" href="#generics">Generics</a></h1>
|
||||||
|
<h3 id="functions"><a class="header" href="#functions">Functions</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blanks to make it work
|
||||||
|
struct A; // Concrete type `A`.
|
||||||
|
struct S(A); // Concrete type `S`.
|
||||||
|
struct SGen<T>(T); // Generic type `SGen`.
|
||||||
|
|
||||||
|
fn reg_fn(_s: S) {}
|
||||||
|
|
||||||
|
fn gen_spec_t(_s: SGen<A>) {}
|
||||||
|
|
||||||
|
fn gen_spec_i32(_s: SGen<i32>) {}
|
||||||
|
|
||||||
|
fn generic<T>(_s: SGen<T>) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Using the non-generic functions
|
||||||
|
reg_fn(__); // Concrete type.
|
||||||
|
gen_spec_t(__); // Implicitly specified type parameter `A`.
|
||||||
|
gen_spec_i32(__); // Implicitly specified type parameter `i32`.
|
||||||
|
|
||||||
|
// Explicitly specified type parameter `char` to `generic()`.
|
||||||
|
generic::<char>(__);
|
||||||
|
|
||||||
|
// Implicitly specified type parameter `char` to `generic()`.
|
||||||
|
generic(__);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟 A function call with explicitly specified type parameters looks like: <code>fun::<A, B, ...>()</code>.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Implement the generic function below.
|
||||||
|
fn sum
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(5, sum(2i8, 3i8));
|
||||||
|
assert_eq!(50, sum(20, 30));
|
||||||
|
assert_eq!(2.46, sum(1.23, 1.23));
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="struct-and-impl"><a class="header" href="#struct-and-impl">Struct and <code>impl</code></a></h3>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Implement struct Point to make it work.
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let integer = Point { x: 5, y: 10 };
|
||||||
|
let float = Point { x: 1.0, y: 4.0 };
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Modify this struct to make the code work
|
||||||
|
struct Point<T> {
|
||||||
|
x: T,
|
||||||
|
y: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// DON'T modify this code.
|
||||||
|
let p = Point{x: 5, y : "hello".to_string()};
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Add generic for Val to make the code work, DON'T modify the code in `main`.
|
||||||
|
struct Val {
|
||||||
|
val: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Val {
|
||||||
|
fn value(&self) -> &f64 {
|
||||||
|
&self.val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = Val{ val: 3.0 };
|
||||||
|
let y = Val{ val: "hello".to_string()};
|
||||||
|
println!("{}, {}", x.value(), y.value());
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="method"><a class="header" href="#method">Method</a></h3>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">struct Point<T, U> {
|
||||||
|
x: T,
|
||||||
|
y: U,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, U> Point<T, U> {
|
||||||
|
// Implement mixup to make it work, DON'T modify other code.
|
||||||
|
fn mixup
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let p1 = Point { x: 5, y: 10 };
|
||||||
|
let p2 = Point { x: "Hello", y: '中'};
|
||||||
|
|
||||||
|
let p3 = p1.mixup(p2);
|
||||||
|
|
||||||
|
assert_eq!(p3.x, 5);
|
||||||
|
assert_eq!(p3.y, '中');
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the errors to make the code work.
|
||||||
|
struct Point<T> {
|
||||||
|
x: T,
|
||||||
|
y: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Point<f32> {
|
||||||
|
fn distance_from_origin(&self) -> f32 {
|
||||||
|
(self.x.powi(2) + self.y.powi(2)).sqrt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let p = Point{x: 5, y: 10};
|
||||||
|
println!("{}",p.distance_from_origin());
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/generics.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../generics-traits/intro.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="../generics-traits/const-generics.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="../generics-traits/intro.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="../generics-traits/const-generics.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
229
generics-traits/intro.html
Normal file
229
generics-traits/intro.html
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Generics and Traits - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/generics-traits/intro.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="generics-and-traits"><a class="header" href="#generics-and-traits">Generics and Traits</a></h1>
|
||||||
|
<p>Learning resources:</p>
|
||||||
|
<ul>
|
||||||
|
<li>English: <a href="https://doc.rust-lang.org/book/ch10-00-generics.html">Rust Book 10.1, 10.2</a></li>
|
||||||
|
<li>简体中文: <a href="https://course.rs/basic/trait/intro.html">Rust语言圣经 - 模式匹配</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../method.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="../generics-traits/generics.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="../method.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="../generics-traits/generics.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
442
generics-traits/trait-object.html
Normal file
442
generics-traits/trait-object.html
Normal file
@ -0,0 +1,442 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Trait Object - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/generics-traits/trait-object.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="trait-object"><a class="header" href="#trait-object">Trait Object</a></h1>
|
||||||
|
<p>In <a href="https://practice.rs/generics-traits/traits.html#returning-types-that-implement-traits">traits chapter</a> we have seen that we can't use <code>impl Trait</code> when returning multiple types.</p>
|
||||||
|
<p>Another limitation of arrays is that they can only store elements of one type. Using enums is not a bad solution when we have a fixed set of types at compile time, but trait objects would be more flexible and powerful.</p>
|
||||||
|
<h2 id="returning-traits-with-dyn"><a class="header" href="#returning-traits-with-dyn">Returning Traits with dyn</a></h2>
|
||||||
|
<p>The Rust compiler needs to know how much space a function's return type requires. Because the different implementations of a trait probably uses different amounts of memory, functions need to either return a concrete type or the same type when using <code>impl Trait</code>, or return a trait object with <code>dyn</code>.</p>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
trait Bird {
|
||||||
|
fn quack(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Duck;
|
||||||
|
impl Duck {
|
||||||
|
fn swim(&self) {
|
||||||
|
println!("Look, the duck is swimming")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct Swan;
|
||||||
|
impl Swan {
|
||||||
|
fn fly(&self) {
|
||||||
|
println!("Look, the duck.. oh sorry, the swan is flying")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bird for Duck {
|
||||||
|
fn quack(&self) -> String{
|
||||||
|
"duck duck".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bird for Swan {
|
||||||
|
fn quack(&self) -> String{
|
||||||
|
"swan swan".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// FILL in the blank.
|
||||||
|
let duck = __;
|
||||||
|
duck.swim();
|
||||||
|
|
||||||
|
let bird = hatch_a_bird(2);
|
||||||
|
// This bird has forgotten how to swim, so below line will cause an error.
|
||||||
|
// bird.swim();
|
||||||
|
// But it can quak.
|
||||||
|
assert_eq!(bird.quack(), "duck duck");
|
||||||
|
|
||||||
|
let bird = hatch_a_bird(1);
|
||||||
|
// This bird has forgotten how to fly, so below line will cause an error.
|
||||||
|
// bird.fly();
|
||||||
|
// But it can quak too.
|
||||||
|
assert_eq!(bird.quack(), "swan swan");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMPLEMENT this function.
|
||||||
|
fn hatch_a_bird...
|
||||||
|
</code></pre></pre>
|
||||||
|
<h2 id="array-with-trait-objects"><a class="header" href="#array-with-trait-objects">Array with trait objects</a></h2>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">trait Bird {
|
||||||
|
fn quack(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Duck;
|
||||||
|
impl Duck {
|
||||||
|
fn fly(&self) {
|
||||||
|
println!("Look, the duck is flying")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
struct Swan;
|
||||||
|
impl Swan {
|
||||||
|
fn fly(&self) {
|
||||||
|
println!("Look, the duck.. oh sorry, the swan is flying")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bird for Duck {
|
||||||
|
fn quack(&self) {
|
||||||
|
println!("{}", "duck duck");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Bird for Swan {
|
||||||
|
fn quack(&self) {
|
||||||
|
println!("{}", "swan swan");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// FILL in the blank to make the code work.
|
||||||
|
let birds __;
|
||||||
|
|
||||||
|
for bird in birds {
|
||||||
|
bird.quack();
|
||||||
|
// When duck and swan turn into Birds, they all forgot how to fly, only remember how to quack.
|
||||||
|
// So, the code below will cause an error.
|
||||||
|
// bird.fly();
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="dyn-and-boxdyn"><a class="header" href="#dyn-and-boxdyn"><code>&dyn</code> and <code>Box<dyn></code></a></h2>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FILL in the blanks.
|
||||||
|
trait Draw {
|
||||||
|
fn draw(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Draw for u8 {
|
||||||
|
fn draw(&self) -> String {
|
||||||
|
format!("u8: {}", *self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Draw for f64 {
|
||||||
|
fn draw(&self) -> String {
|
||||||
|
format!("f64: {}", *self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = 1.1f64;
|
||||||
|
let y = 8u8;
|
||||||
|
|
||||||
|
// Draw x.
|
||||||
|
draw_with_box(__);
|
||||||
|
|
||||||
|
// Draw y.
|
||||||
|
draw_with_ref(&y);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_with_box(x: Box<dyn Draw>) {
|
||||||
|
x.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_with_ref(x: __) {
|
||||||
|
x.draw();
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="static-and-dynamic-dispatch"><a class="header" href="#static-and-dynamic-dispatch">Static and Dynamic dispatch</a></h2>
|
||||||
|
<p>When we use trait bounds on generics, the compiler generates nongeneric implementations of functions and methods for each concrete type that we use in place of a generic type parameter. The code that results from monomorphization is doing static dispatch, which is when the compiler knows what method you’re calling at compile time.</p>
|
||||||
|
<p>When we use trait objects, Rust must use dynamic dispatch. The compiler doesn’t know all the types that might be used with the code that is using trait objects, so it doesn’t know which method implemented on which type to call. Instead, at runtime, Rust uses the pointers inside the trait object to know which method to call. There is a runtime cost when this lookup happens that doesn’t occur with static dispatch. Dynamic dispatch also prevents the compiler from choosing to inline a method’s code, which in turn prevents some optimizations.</p>
|
||||||
|
<p>However, we do get extra flexibility when using dynamic dispatch.</p>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
trait Foo {
|
||||||
|
fn method(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for u8 {
|
||||||
|
fn method(&self) -> String { format!("u8: {}", *self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Foo for String {
|
||||||
|
fn method(&self) -> String { format!("string: {}", *self) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// IMPLEMENT below with generics.
|
||||||
|
fn static_dispatch...
|
||||||
|
|
||||||
|
// Implement below with trait objects.
|
||||||
|
fn dynamic_dispatch...
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = 5u8;
|
||||||
|
let y = "Hello".to_string();
|
||||||
|
|
||||||
|
static_dispatch(x);
|
||||||
|
dynamic_dispatch(&y);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="object-safe"><a class="header" href="#object-safe">Object safe</a></h2>
|
||||||
|
<p>You can only make object-safe traits into trait objects. A trait is object safe if all the methods defined in the trait have the following properties:</p>
|
||||||
|
<ul>
|
||||||
|
<li>The return type isn’t <code>Self</code>.</li>
|
||||||
|
<li>There are no generic type parameters.</li>
|
||||||
|
</ul>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Use at least two approaches to make it work.
|
||||||
|
// DON'T add/remove any code line.
|
||||||
|
trait MyTrait {
|
||||||
|
fn f(&self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MyTrait for u32 {
|
||||||
|
fn f(&self) -> Self { 42 }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MyTrait for String {
|
||||||
|
fn f(&self) -> Self { self.clone() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn my_function(x: Box<dyn MyTrait>) {
|
||||||
|
x.f()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
my_function(Box::new(13_u32));
|
||||||
|
my_function(Box::new(String::from("abc")));
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/trait-object.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../generics-traits/traits.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="../generics-traits/advanced-traits.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="../generics-traits/traits.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="../generics-traits/advanced-traits.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
678
generics-traits/traits.html
Normal file
678
generics-traits/traits.html
Normal file
@ -0,0 +1,678 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Traits - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/generics-traits/traits.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="traits"><a class="header" href="#traits">Traits</a></h1>
|
||||||
|
<p>A trait tells the Rust compiler about functionality a particular type has and can share with other types. We can use traits to define shared behavior in an abstract way. We can use trait bounds to specify that a generic type can be any type that has certain behavior.</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>Note: Traits are similar to interfaces in other languages, although with some differences.</p>
|
||||||
|
</blockquote>
|
||||||
|
<h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
struct Sheep { naked: bool, name: String }
|
||||||
|
|
||||||
|
trait Animal {
|
||||||
|
// Associated function signature; `Self` refers to the implementor type.
|
||||||
|
fn new(name: String) -> Self;
|
||||||
|
|
||||||
|
// Method signatures; these will return a string.
|
||||||
|
fn name(&self) -> String;
|
||||||
|
|
||||||
|
fn noise(&self) -> String;
|
||||||
|
|
||||||
|
// Traits can provide default method definitions.
|
||||||
|
fn talk(&self) {
|
||||||
|
println!("{} says {}", self.name(), self.noise());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sheep {
|
||||||
|
fn is_naked(&self) -> bool {
|
||||||
|
self.naked
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shear(&mut self) {
|
||||||
|
if self.is_naked() {
|
||||||
|
// Implementor methods can use the implementor's trait methods.
|
||||||
|
println!("{} is already naked...", self.name());
|
||||||
|
} else {
|
||||||
|
println!("{} gets a haircut!", self.name);
|
||||||
|
|
||||||
|
self.naked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement the `Animal` trait for `Sheep`.
|
||||||
|
impl Animal for Sheep {
|
||||||
|
// `Self` is the implementor type: `Sheep`.
|
||||||
|
fn new(name: String) -> Sheep {
|
||||||
|
Sheep { name: name, naked: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> String {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn noise(&self) -> String {
|
||||||
|
if self.is_naked() {
|
||||||
|
"baaaaah?".to_string()
|
||||||
|
} else {
|
||||||
|
"baaaaah!".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default trait methods can be overridden.
|
||||||
|
fn talk(&self) {
|
||||||
|
// For example, we can add some quiet contemplation.
|
||||||
|
println!("{} pauses briefly... {}", self.name, self.noise());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Type annotation is necessary in this case.
|
||||||
|
let mut dolly: Sheep = Animal::new("Dolly".to_string());
|
||||||
|
// TODO ^ Try removing the type annotations.
|
||||||
|
|
||||||
|
dolly.talk();
|
||||||
|
dolly.shear();
|
||||||
|
dolly.talk();
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="exercises"><a class="header" href="#exercises">Exercises</a></h2>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the two impl blocks to make the code work.
|
||||||
|
// DON'T modify the code in `main`.
|
||||||
|
trait Hello {
|
||||||
|
fn say_hi(&self) -> String {
|
||||||
|
String::from("hi")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn say_something(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Student {}
|
||||||
|
impl Hello for Student {
|
||||||
|
}
|
||||||
|
struct Teacher {}
|
||||||
|
impl Hello for Teacher {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let s = Student {};
|
||||||
|
assert_eq!(s.say_hi(), "hi");
|
||||||
|
assert_eq!(s.say_something(), "I'm a good student");
|
||||||
|
|
||||||
|
let t = Teacher {};
|
||||||
|
assert_eq!(t.say_hi(), "Hi, I'm your new teacher");
|
||||||
|
assert_eq!(t.say_something(), "I'm not a bad teacher");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="derive"><a class="header" href="#derive">Derive</a></h3>
|
||||||
|
<p>The compiler is capable of providing basic implementations for some traits via
|
||||||
|
the <code>#[derive]</code> attribute. For more info, please visit <a href="https://doc.rust-lang.org/book/appendix-03-derivable-traits.html">here</a>.</p>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// `Centimeters`, a tuple struct that can be compared
|
||||||
|
#[derive(PartialEq, PartialOrd)]
|
||||||
|
struct Centimeters(f64);
|
||||||
|
|
||||||
|
// `Inches`, a tuple struct that can be printed
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Inches(i32);
|
||||||
|
|
||||||
|
impl Inches {
|
||||||
|
fn to_centimeters(&self) -> Centimeters {
|
||||||
|
let &Inches(inches) = self;
|
||||||
|
|
||||||
|
Centimeters(inches as f64 * 2.54)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ADD some attributes to make the code work!
|
||||||
|
// DON'T modify other code!
|
||||||
|
struct Seconds(i32);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _one_second = Seconds(1);
|
||||||
|
|
||||||
|
println!("One second looks like: {:?}", _one_second);
|
||||||
|
let _this_is_true = (_one_second == _one_second);
|
||||||
|
let _this_is_false = (_one_second > _one_second);
|
||||||
|
|
||||||
|
let foot = Inches(12);
|
||||||
|
|
||||||
|
println!("One foot equals {:?}", foot);
|
||||||
|
|
||||||
|
let meter = Centimeters(100.0);
|
||||||
|
|
||||||
|
let cmp =
|
||||||
|
if foot.to_centimeters() < meter {
|
||||||
|
"smaller"
|
||||||
|
} else {
|
||||||
|
"bigger"
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("One foot is {} than one meter.", cmp);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="operator"><a class="header" href="#operator">Operator</a></h3>
|
||||||
|
<p>In Rust, many of the operators can be overloaded via traits. That is, some operators can be used to accomplish different tasks based on their input arguments. This is possible because operators are syntactic sugar for method calls. For example, the + operator in a + b calls the add method (as in a.add(b)). This add method is part of the Add trait. Hence, the + operator can be used by any implementor of the Add trait.</p>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
use std::ops;
|
||||||
|
|
||||||
|
// Implement fn multiply to make the code work.
|
||||||
|
// As mentioned above, `+` needs `T` to implement `std::ops::Add` Trait.
|
||||||
|
// So, what about `*`? You can find the answer here: https://doc.rust-lang.org/core/ops/
|
||||||
|
fn multiply
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
assert_eq!(6, multiply(2u8, 3u8));
|
||||||
|
assert_eq!(5.0, multiply(1.0, 5.0));
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix the errors, DON'T modify the code in `main`.
|
||||||
|
use std::ops;
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
struct Bar;
|
||||||
|
|
||||||
|
struct FooBar;
|
||||||
|
|
||||||
|
struct BarFoo;
|
||||||
|
|
||||||
|
// The `std::ops::Add` trait is used to specify the functionality of `+`.
|
||||||
|
// Here, we make `Add<Bar>` - the trait for addition with a RHS of type `Bar`.
|
||||||
|
// The following block implements the operation: Foo + Bar = FooBar
|
||||||
|
impl ops::Add<Bar> for Foo {
|
||||||
|
type Output = FooBar;
|
||||||
|
|
||||||
|
fn add(self, _rhs: Bar) -> FooBar {
|
||||||
|
FooBar
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ops::Sub<Foo> for Bar {
|
||||||
|
type Output = BarFoo;
|
||||||
|
|
||||||
|
fn sub(self, _rhs: Foo) -> BarFoo {
|
||||||
|
BarFoo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// DON'T modify the code below.
|
||||||
|
// You need to derive some trait for FooBar to make it comparable.
|
||||||
|
assert_eq!(Foo + Bar, FooBar);
|
||||||
|
assert_eq!(Foo - Bar, BarFoo);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="use-trait-as-function-parameters"><a class="header" href="#use-trait-as-function-parameters">Use trait as function parameters</a></h3>
|
||||||
|
<p>Instead of a concrete type for the item parameter, we specify the impl keyword and the trait name. This parameter accepts any type that implements the specified trait.</p>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Implement `fn summary` to make the code work.
|
||||||
|
// Fix the errors without removing any code line
|
||||||
|
trait Summary {
|
||||||
|
fn summarize(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Post {
|
||||||
|
title: String,
|
||||||
|
author: String,
|
||||||
|
content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Summary for Post {
|
||||||
|
fn summarize(&self) -> String {
|
||||||
|
format!("The author of post {} is {}", self.title, self.author)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Weibo {
|
||||||
|
username: String,
|
||||||
|
content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Summary for Weibo {
|
||||||
|
fn summarize(&self) -> String {
|
||||||
|
format!("{} published a weibo {}", self.username, self.content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let post = Post {
|
||||||
|
title: "Popular Rust".to_string(),
|
||||||
|
author: "Sunface".to_string(),
|
||||||
|
content: "Rust is awesome!".to_string(),
|
||||||
|
};
|
||||||
|
let weibo = Weibo {
|
||||||
|
username: "sunface".to_string(),
|
||||||
|
content: "Weibo seems to be worse than Tweet".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
summary(post);
|
||||||
|
summary(weibo);
|
||||||
|
|
||||||
|
println!("{:?}", post);
|
||||||
|
println!("{:?}", weibo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement `fn summary` below.
|
||||||
|
</code></pre></pre>
|
||||||
|
<h3 id="returning-types-that-implement-traits"><a class="header" href="#returning-types-that-implement-traits">Returning Types that Implement Traits</a></h3>
|
||||||
|
<p>We can also use the impl Trait syntax in the return position to return a value of some type that implements a trait.</p>
|
||||||
|
<p>However, you can only use impl Trait if you’re returning a single type, use Trait Objects instead when you really need to return several types.</p>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
struct Sheep {}
|
||||||
|
struct Cow {}
|
||||||
|
|
||||||
|
trait Animal {
|
||||||
|
fn noise(&self) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animal for Sheep {
|
||||||
|
fn noise(&self) -> String {
|
||||||
|
"baaaaah!".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Animal for Cow {
|
||||||
|
fn noise(&self) -> String {
|
||||||
|
"moooooo!".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns some struct that implements Animal, but we don't know which one at compile time.
|
||||||
|
// FIX the errors here, you can make a fake random, or you can use trait object.
|
||||||
|
fn random_animal(random_number: f64) -> impl Animal {
|
||||||
|
if random_number < 0.5 {
|
||||||
|
Sheep {}
|
||||||
|
} else {
|
||||||
|
Cow {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let random_number = 0.234;
|
||||||
|
let animal = random_animal(random_number);
|
||||||
|
println!("You've randomly chosen an animal, and it says {}", animal.noise());
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="trait-bound"><a class="header" href="#trait-bound">Trait bound</a></h3>
|
||||||
|
<p>The <code>impl Trait</code> syntax works for straightforward cases but is actually syntax sugar for a longer form, which is called a trait bound.</p>
|
||||||
|
<p>When working with generics, the type parameters often must use traits as bounds to stipulate what functionality a type implements.</p>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
assert_eq!(sum(1, 2), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement `fn sum` with trait bound in two ways.
|
||||||
|
fn sum<T>(x: T, y: T) -> T {
|
||||||
|
x + y
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// FIX the errors.
|
||||||
|
struct Pair<T> {
|
||||||
|
x: T,
|
||||||
|
y: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Pair<T> {
|
||||||
|
fn new(x: T, y: T) -> Self {
|
||||||
|
Self {
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: std::fmt::Debug + PartialOrd> Pair<T> {
|
||||||
|
fn cmp_display(&self) {
|
||||||
|
if self.x >= self.y {
|
||||||
|
println!("The largest member is x = {:?}", self.x);
|
||||||
|
} else {
|
||||||
|
println!("The largest member is y = {:?}", self.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Unit(i32);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let pair = Pair{
|
||||||
|
x: Unit(1),
|
||||||
|
y: Unit(3)
|
||||||
|
};
|
||||||
|
|
||||||
|
pair.cmp_display();
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fill in the blanks to make it work
|
||||||
|
fn example1() {
|
||||||
|
// `T: Trait` is the commonly used way.
|
||||||
|
// `T: Fn(u32) -> u32` specifies that we can only pass a closure to `T`.
|
||||||
|
struct Cacher<T: Fn(u32) -> u32> {
|
||||||
|
calculation: T,
|
||||||
|
value: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Fn(u32) -> u32> Cacher<T> {
|
||||||
|
fn new(calculation: T) -> Cacher<T> {
|
||||||
|
Cacher {
|
||||||
|
calculation,
|
||||||
|
value: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value(&mut self, arg: u32) -> u32 {
|
||||||
|
match self.value {
|
||||||
|
Some(v) => v,
|
||||||
|
None => {
|
||||||
|
let v = (self.calculation)(arg);
|
||||||
|
self.value = Some(v);
|
||||||
|
v
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cacher = Cacher::new(|x| x+1);
|
||||||
|
assert_eq!(cacher.value(10), __);
|
||||||
|
assert_eq!(cacher.value(15), __);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn example2() {
|
||||||
|
// We can also use `where` to construct `T`
|
||||||
|
struct Cacher<T>
|
||||||
|
where T: Fn(u32) -> u32,
|
||||||
|
{
|
||||||
|
calculation: T,
|
||||||
|
value: Option<u32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Cacher<T>
|
||||||
|
where T: Fn(u32) -> u32,
|
||||||
|
{
|
||||||
|
fn new(calculation: T) -> Cacher<T> {
|
||||||
|
Cacher {
|
||||||
|
calculation,
|
||||||
|
value: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value(&mut self, arg: u32) -> u32 {
|
||||||
|
match self.value {
|
||||||
|
Some(v) => v,
|
||||||
|
None => {
|
||||||
|
let v = (self.calculation)(arg);
|
||||||
|
self.value = Some(v);
|
||||||
|
v
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cacher = Cacher::new(|x| x+1);
|
||||||
|
assert_eq!(cacher.value(20), __);
|
||||||
|
assert_eq!(cacher.value(25), __);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
example1();
|
||||||
|
example2();
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/generics-traits/traits.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../generics-traits/const-generics.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="../generics-traits/trait-object.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="../generics-traits/const-generics.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="../generics-traits/trait-object.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
224
global-variables.html
Normal file
224
global-variables.html
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Global variables TODO - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/global-variables.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="global-variables"><a class="header" href="#global-variables">Global variables</a></h1>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="threads/send-sync.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="errors.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="threads/send-sync.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="errors.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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
83
highlight.css
Normal file
83
highlight.css
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* An increased contrast highlighting scheme loosely based on the
|
||||||
|
* "Base16 Atelier Dune Light" theme by Bram de Haan
|
||||||
|
* (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune)
|
||||||
|
* Original Base16 color scheme by Chris Kempson
|
||||||
|
* (https://github.com/chriskempson/base16)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Comment */
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote {
|
||||||
|
color: #575757;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Red */
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-tag,
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-link,
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-selector-id,
|
||||||
|
.hljs-selector-class {
|
||||||
|
color: #d70025;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Orange */
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-meta,
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-builtin-name,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-params {
|
||||||
|
color: #b21e00;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Green */
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-bullet {
|
||||||
|
color: #008200;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blue */
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-section {
|
||||||
|
color: #0030f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Purple */
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag {
|
||||||
|
color: #9d00ec;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
background: #f6f7f6;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-emphasis {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition {
|
||||||
|
color: #22863a;
|
||||||
|
background-color: #f0fff4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion {
|
||||||
|
color: #b31d28;
|
||||||
|
background-color: #ffeef0;
|
||||||
|
}
|
54
highlight.js
Normal file
54
highlight.js
Normal file
File diff suppressed because one or more lines are too long
258
index.html
Normal file
258
index.html
Normal file
@ -0,0 +1,258 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Rust By Practice - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/why-exercise.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>
|
||||||
|
<div align="center">
|
||||||
|
<img src="https://github.com/sunface/rust-by-practice/blob/master/en/assets/header.jpg?raw=true">
|
||||||
|
</div>
|
||||||
|
<p align="center">Practice Rust with challenging examples, exercises and projects</p>
|
||||||
|
<div align="center">
|
||||||
|
<p><a href="https://github.com/sunface/rust-by-practice/stargazers"><img src="https://img.shields.io/github/stars/sunface/rust-by-practice?style=flat" alt="Stars Count" /></a> <a href="https://github.com/naaive/orange/network/members"><img src="https://img.shields.io/github/forks/sunface/rust-by-practice.svg?style=flat" alt="Forks Count" /></a>
|
||||||
|
<a href="https://github.com/sunface/rust-by-practice/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-mit-green?style=flat" alt="LICENSE" /></a></p>
|
||||||
|
</div>
|
||||||
|
<p>This book was designed for easily diving into and getting skilled with Rust, and it's very easy to use: All you need to do is to make each exercise compile without ERRORS and Panics !</p>
|
||||||
|
<h2 id="reading-online"><a class="header" href="#reading-online">Reading online</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://practice.rs">English</a></li>
|
||||||
|
<li><a href="https://zh.practice.rs">简体中文</a></li>
|
||||||
|
</ul>
|
||||||
|
<h2 id="running-locally"><a class="header" href="#running-locally">Running locally</a></h2>
|
||||||
|
<p>We use <a href="https://rust-lang.github.io/mdBook/">mdbook</a> building our exercises. You can run locally with below steps:</p>
|
||||||
|
<pre><code class="language-shell">$ git clone https://github.com/sunface/rust-by-practice
|
||||||
|
$ cargo install mdbook
|
||||||
|
$ cd rust-by-practice && mdbook serve en/
|
||||||
|
</code></pre>
|
||||||
|
<h2 id="features"><a class="header" href="#features">Features</a></h2>
|
||||||
|
<p>Part of our examples and exercises are borrowed from <a href="https://github.com/rust-lang/rust-by-example">Rust By Example</a>, thanks for your great works!</p>
|
||||||
|
<p>Although they are so awesome, we have our own secret weapons :)</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<p>There are three parts in each chapter: examples, exercises and practices</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Besides examples, we have <code>a lot of exercises</code>, you can Read, Edit and Run them ONLINE</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Covering nearly all aspects of Rust, such as async/await, threads, sync primitives, optimizing, standard libraries, tool chain, data structures and algorithms etc.</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>Every exercise has its own solutions</p>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<p>The overall difficulties are a bit higher and from easy to super hard: easy 🌟 medium 🌟🌟 hard 🌟🌟🌟 super hard 🌟🌟🌟🌟</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>What we want to do is to fill the gap between learning and getting started with real projects!</strong></p>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
|
||||||
|
<a rel="next prefetch" href="elegant-code-base.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="next prefetch" href="elegant-code-base.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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
481
lifetime/advance.html
Normal file
481
lifetime/advance.html
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>advanced - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/lifetime/advance.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="advance-lifetime"><a class="header" href="#advance-lifetime">Advance lifetime</a></h1>
|
||||||
|
<h2 id="trait-bounds"><a class="header" href="#trait-bounds">Trait Bounds</a></h2>
|
||||||
|
<p>Just like generic types can be bounded, lifetimes can also be bounded as below:</p>
|
||||||
|
<ul>
|
||||||
|
<li><code>T: 'a</code>,all references in <code>T</code> must outlive the lifetime <code>'a</code></li>
|
||||||
|
<li><code>T: Trait + 'a</code>: <code>T</code> must implement trait <code>Trait</code> and all references in <code>T</code> must outlive <code>'a</code></li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::fmt::Debug; // Trait to bound with.
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Ref<'a, T: 'a>(&'a T);
|
||||||
|
// `Ref` contains a reference to a generic type `T` that has
|
||||||
|
// an unknown lifetime `'a`. `T` is bounded such that any
|
||||||
|
// *references* in `T` must outlive `'a`. Additionally, the lifetime
|
||||||
|
// of `Ref` may not exceed `'a`.
|
||||||
|
|
||||||
|
// A generic function which prints using the `Debug` trait.
|
||||||
|
fn print<T>(t: T) where
|
||||||
|
T: Debug {
|
||||||
|
println!("`print`: t is {:?}", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here a reference to `T` is taken where `T` implements
|
||||||
|
// `Debug` and all *references* in `T` outlive `'a`. In
|
||||||
|
// addition, `'a` must outlive the function.
|
||||||
|
fn print_ref<'a, T>(t: &'a T) where
|
||||||
|
T: Debug + 'a {
|
||||||
|
println!("`print_ref`: t is {:?}", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = 7;
|
||||||
|
let ref_x = Ref(&x);
|
||||||
|
|
||||||
|
print_ref(&ref_x);
|
||||||
|
print(ref_x);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Annotate struct with lifetime:
|
||||||
|
1. `r` and `s` must have different lifetimes
|
||||||
|
2. lifetime of `s` is bigger than that of 'r'
|
||||||
|
*/
|
||||||
|
struct DoubleRef<T> {
|
||||||
|
r: &T,
|
||||||
|
s: &T
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
println!("Success!")
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Adding trait bounds to make it work */
|
||||||
|
struct ImportantExcerpt<'a> {
|
||||||
|
part: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> ImportantExcerpt<'a> {
|
||||||
|
fn announce_and_return_part(&'a self, announcement: &'b str) -> &'b str {
|
||||||
|
println!("Attention please: {}", announcement);
|
||||||
|
self.part
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Success!")
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Adding trait bounds to make it work */
|
||||||
|
fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) {
|
||||||
|
y = x;
|
||||||
|
let r: &'b &'a i32 = &&0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Success!")
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="hrtbhigher-ranked-trait-bounds"><a class="header" href="#hrtbhigher-ranked-trait-bounds">HRTB(Higher-ranked trait bounds)</a></h2>
|
||||||
|
<p>Type bounds may be higher ranked over lifetimes. These bounds specify a bound is true for all lifetimes. For example, a bound such as <code>for<'a> &'a T: PartialEq<i32></code> would require an implementation like:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>impl<'a> PartialEq<i32> for &'a T {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>and could then be used to compare a <code>&'a T</code> with any lifetime to an <code>i32</code>.</p>
|
||||||
|
<p>Only a higher-ranked bound can be used here, because the lifetime of the reference is shorter than any possible lifetime parameter on the function.</p>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Adding HRTB to make it work!*/
|
||||||
|
fn call_on_ref_zero<'a, F>(f: F) where F: Fn(&'a i32) {
|
||||||
|
let zero = 0;
|
||||||
|
f(&zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="nll-non-lexical-lifetime"><a class="header" href="#nll-non-lexical-lifetime">NLL (Non-Lexical Lifetime)</a></h2>
|
||||||
|
<p>Before explaining NLL, let's see some code first:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||||
|
let mut s = String::from("hello");
|
||||||
|
|
||||||
|
let r1 = &s;
|
||||||
|
let r2 = &s;
|
||||||
|
println!("{} and {}", r1, r2);
|
||||||
|
|
||||||
|
let r3 = &mut s;
|
||||||
|
println!("{}", r3);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<p>Based on our current knowledge, this code will cause en error due to violating the borrowing rules in Rust.</p>
|
||||||
|
<p>But if you <code>cargo run</code> it, then everything will be ok, so what's going on here?</p>
|
||||||
|
<p>The ability of the compiler to tell that a reference is no longer used at a point before the end of the scope, is called <strong>Non-Lexical Lifetimes</strong> (<strong>NLL</strong> for short).</p>
|
||||||
|
<p>With this ability the compiler knows when is the last time that a reference is used and optimizing the borrowing rules based on this knowledge.</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>let mut u = 0i32;
|
||||||
|
let mut v = 1i32;
|
||||||
|
let mut w = 2i32;
|
||||||
|
|
||||||
|
// lifetime of `a` = α ∪ β ∪ γ
|
||||||
|
let mut a = &mut u; // --+ α. lifetime of `&mut u` --+ lexical "lifetime" of `&mut u`,`&mut u`, `&mut w` and `a`
|
||||||
|
use(a); // | |
|
||||||
|
*a = 3; // <-----------------+ |
|
||||||
|
... // |
|
||||||
|
a = &mut v; // --+ β. lifetime of `&mut v` |
|
||||||
|
use(a); // | |
|
||||||
|
*a = 4; // <-----------------+ |
|
||||||
|
... // |
|
||||||
|
a = &mut w; // --+ γ. lifetime of `&mut w` |
|
||||||
|
use(a); // | |
|
||||||
|
*a = 5; // <-----------------+ <--------------------------+
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<h2 id="reborrow"><a class="header" href="#reborrow">Reborrow</a></h2>
|
||||||
|
<p>After learning NLL, we can easily understand reborrow now.</p>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021">#[derive(Debug)]
|
||||||
|
struct Point {
|
||||||
|
x: i32,
|
||||||
|
y: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Point {
|
||||||
|
fn move_to(&mut self, x: i32, y: i32) {
|
||||||
|
self.x = x;
|
||||||
|
self.y = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut p = Point { x: 0, y: 0 };
|
||||||
|
let r = &mut p;
|
||||||
|
// Here comes the reborrow
|
||||||
|
let rr: &Point = &*r;
|
||||||
|
|
||||||
|
println!("{:?}", rr); // Reborrow ends here, NLL introduced
|
||||||
|
|
||||||
|
// Reborrow is over, we can continue using `r` now
|
||||||
|
r.move_to(10, 10);
|
||||||
|
println!("{:?}", r);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work by reordering some code */
|
||||||
|
fn main() {
|
||||||
|
let mut data = 10;
|
||||||
|
let ref1 = &mut data;
|
||||||
|
let ref2 = &mut *ref1;
|
||||||
|
|
||||||
|
*ref1 += 1;
|
||||||
|
*ref2 += 2;
|
||||||
|
|
||||||
|
println!("{}", data);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="unbound-lifetime"><a class="header" href="#unbound-lifetime">Unbound lifetime</a></h2>
|
||||||
|
<p>See more info in <a href="https://doc.rust-lang.org/nomicon/unbounded-lifetimes.html">Nomicon - Unbounded Lifetimes</a>.</p>
|
||||||
|
<h2 id="more-elision-rules"><a class="header" href="#more-elision-rules">More elision rules</a></h2>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>impl<'a> Reader for BufReader<'a> {
|
||||||
|
// 'a is not used in the following methods
|
||||||
|
}
|
||||||
|
|
||||||
|
// can be written as :
|
||||||
|
impl Reader for BufReader<'_> {
|
||||||
|
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>// Rust 2015
|
||||||
|
struct Ref<'a, T: 'a> {
|
||||||
|
field: &'a T
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rust 2018
|
||||||
|
struct Ref<'a, T> {
|
||||||
|
field: &'a T
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<h2 id="a-difficult-exercise"><a class="header" href="#a-difficult-exercise">A difficult exercise</a></h2>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work */
|
||||||
|
struct Interface<'a> {
|
||||||
|
manager: &'a mut Manager<'a>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Interface<'a> {
|
||||||
|
pub fn noop(self) {
|
||||||
|
println!("interface consumed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Manager<'a> {
|
||||||
|
text: &'a str
|
||||||
|
}
|
||||||
|
|
||||||
|
struct List<'a> {
|
||||||
|
manager: Manager<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> List<'a> {
|
||||||
|
pub fn get_interface(&'a mut self) -> Interface {
|
||||||
|
Interface {
|
||||||
|
manager: &mut self.manager
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut list = List {
|
||||||
|
manager: Manager {
|
||||||
|
text: "hello"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
list.get_interface().noop();
|
||||||
|
|
||||||
|
println!("Interface should be dropped here and the borrow released");
|
||||||
|
|
||||||
|
use_list(&list);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn use_list(list: &List) {
|
||||||
|
println!("{}", list.manager.text);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/lifetime/advance.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../lifetime/static.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="../functional-programing/intro.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="../lifetime/static.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="../functional-programing/intro.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
559
lifetime/basic.html
Normal file
559
lifetime/basic.html
Normal file
@ -0,0 +1,559 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>basic - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/lifetime/basic.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>
|
||||||
|
<h2 id="lifetime"><a class="header" href="#lifetime">Lifetime</a></h2>
|
||||||
|
<p>The compiler uses lifetime to ensure all borrows are valid. Typically, a variable's lifetime begins when it is created and ends when it is destroyed.</p>
|
||||||
|
<h2 id="the-scope-of-lifetime"><a class="header" href="#the-scope-of-lifetime">The scope of lifetime</a></h2>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Annotate the lifetime of `i` and `borrow2` */
|
||||||
|
|
||||||
|
// Lifetimes are annotated below with lines denoting the creation
|
||||||
|
// and destruction of each variable.
|
||||||
|
// `i` has the longest lifetime because its scope entirely encloses
|
||||||
|
// both `borrow1` and `borrow2`. The duration of `borrow1` compared
|
||||||
|
// to `borrow2` is irrelevant since they are disjoint.
|
||||||
|
fn main() {
|
||||||
|
let i = 3;
|
||||||
|
{
|
||||||
|
let borrow1 = &i; // `borrow1` lifetime starts. ──┐
|
||||||
|
// │
|
||||||
|
println!("borrow1: {}", borrow1); // │
|
||||||
|
} // `borrow1 ends. ──────────────────────────────────┘
|
||||||
|
{
|
||||||
|
let borrow2 = &i;
|
||||||
|
|
||||||
|
println!("borrow2: {}", borrow2);
|
||||||
|
}
|
||||||
|
} </code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>{
|
||||||
|
let x = 5; // ----------+-- 'b
|
||||||
|
// |
|
||||||
|
let r = &x; // --+-- 'a |
|
||||||
|
// | |
|
||||||
|
println!("r: {}", r); // | |
|
||||||
|
// --+ |
|
||||||
|
} // ----------+
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Annotate `r` and `x` as above, and explain why this code fails to compile, in the lifetime aspect. */
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
{
|
||||||
|
let r; // ---------+-- 'a
|
||||||
|
// |
|
||||||
|
{ // |
|
||||||
|
let x = 5; // -+-- 'b |
|
||||||
|
r = &x; // | |
|
||||||
|
} // -+ |
|
||||||
|
// |
|
||||||
|
println!("r: {}", r); // |
|
||||||
|
} // ---------+
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="lifetime-annotating"><a class="header" href="#lifetime-annotating">Lifetime annotating</a></h2>
|
||||||
|
<p>The <strong>borrow checker uses explicit lifetime annotations</strong> to determine how long a reference should be valid.</p>
|
||||||
|
<p>But for us users, in most cases, there is no need to annotate the lifetime, because there are several elision rules, before learning these rules, we need to know how to annotate lifetime manually.</p>
|
||||||
|
<h4 id="function"><a class="header" href="#function">Function</a></h4>
|
||||||
|
<p>Ignoring elision rules, lifetimes in function signatures have a few constraints:</p>
|
||||||
|
<ul>
|
||||||
|
<li>Any reference must have an annotated lifetime</li>
|
||||||
|
<li>Any reference being returned must have the same lifetime as one of the inputs or be static</li>
|
||||||
|
</ul>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// One input reference with lifetime `'a` which must live
|
||||||
|
// at least as long as the function.
|
||||||
|
fn print_one<'a>(x: &'a i32) {
|
||||||
|
println!("`print_one`: x is {}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mutable references are possible with lifetimes as well.
|
||||||
|
fn add_one<'a>(x: &'a mut i32) {
|
||||||
|
*x += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Multiple elements with different lifetimes. In this case, it
|
||||||
|
// would be fine for both to have the same lifetime `'a`, but
|
||||||
|
// in more complex cases, different lifetimes may be required.
|
||||||
|
fn print_multi<'a, 'b>(x: &'a i32, y: &'b i32) {
|
||||||
|
println!("`print_multi`: x is {}, y is {}", x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returning references that have been passed in is acceptable.
|
||||||
|
// However, the correct lifetime must be returned.
|
||||||
|
fn pass_x<'a, 'b>(x: &'a i32, _: &'b i32) -> &'a i32 { x }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = 7;
|
||||||
|
let y = 9;
|
||||||
|
|
||||||
|
print_one(&x);
|
||||||
|
print_multi(&x, &y);
|
||||||
|
|
||||||
|
let z = pass_x(&x, &y);
|
||||||
|
print_one(z);
|
||||||
|
|
||||||
|
let mut t = 3;
|
||||||
|
add_one(&mut t);
|
||||||
|
print_one(&t);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work by adding proper lifetime annotation */
|
||||||
|
fn longest(x: &str, y: &str) -> &str {
|
||||||
|
if x.len() > y.len() {
|
||||||
|
x
|
||||||
|
} else {
|
||||||
|
y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// `'a` must live longer than the function.
|
||||||
|
// Here, `&String::from("foo")` would create a `String`, followed by a
|
||||||
|
// reference. Then the data is dropped upon exiting the scope, leaving
|
||||||
|
// a reference to invalid data to be returned.
|
||||||
|
|
||||||
|
/* Fix the error in three ways */
|
||||||
|
fn invalid_output<'a>() -> &'a String {
|
||||||
|
&String::from("foo")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// `print_refs` takes two references to `i32` which have different
|
||||||
|
// lifetimes `'a` and `'b`. These two lifetimes must both be at
|
||||||
|
// least as long as the function `print_refs`.
|
||||||
|
fn print_refs<'a, 'b>(x: &'a i32, y: &'b i32) {
|
||||||
|
println!("x is {} and y is {}", x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make it work */
|
||||||
|
// A function which takes no arguments, but has a lifetime parameter `'a`.
|
||||||
|
fn failed_borrow<'a>() {
|
||||||
|
let _x = 12;
|
||||||
|
|
||||||
|
// ERROR: `_x` does not live long enough
|
||||||
|
let y: &'a i32 = &_x;
|
||||||
|
// Attempting to use the lifetime `'a` as an explicit type annotation
|
||||||
|
// inside the function will fail because the lifetime of `&_x` is shorter
|
||||||
|
// than `'a` . A short lifetime cannot be coerced into a longer one.
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let (four, nine) = (4, 9);
|
||||||
|
|
||||||
|
// Borrows (`&`) of both variables are passed into the function.
|
||||||
|
print_refs(&four, &nine);
|
||||||
|
// Any input which is borrowed must outlive the borrower.
|
||||||
|
// In other words, the lifetime of `four` and `nine` must
|
||||||
|
// be longer than that of `print_refs`.
|
||||||
|
|
||||||
|
failed_borrow();
|
||||||
|
// `failed_borrow` contains no references to force `'a` to be
|
||||||
|
// longer than the lifetime of the function, but `'a` is longer.
|
||||||
|
// Because the lifetime is never constrained, it defaults to `'static`.
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="structs"><a class="header" href="#structs">Structs</a></h4>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work by adding proper lifetime annotation */
|
||||||
|
|
||||||
|
// A type `Borrowed` which houses a reference to an
|
||||||
|
// `i32`. The reference to `i32` must outlive `Borrowed`.
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Borrowed(&i32);
|
||||||
|
|
||||||
|
// Similarly, both references here must outlive this structure.
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NamedBorrowed {
|
||||||
|
x: &i32,
|
||||||
|
y: &i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// An enum which is either an `i32` or a reference to one.
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Either {
|
||||||
|
Num(i32),
|
||||||
|
Ref(&i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let x = 18;
|
||||||
|
let y = 15;
|
||||||
|
|
||||||
|
let single = Borrowed(&x);
|
||||||
|
let double = NamedBorrowed { x: &x, y: &y };
|
||||||
|
let reference = Either::Ref(&x);
|
||||||
|
let number = Either::Num(y);
|
||||||
|
|
||||||
|
println!("x is borrowed in {:?}", single);
|
||||||
|
println!("x and y are borrowed in {:?}", double);
|
||||||
|
println!("x is borrowed in {:?}", reference);
|
||||||
|
println!("y is *not* borrowed in {:?}", number);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work */
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NoCopyType {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Example<'a, 'b> {
|
||||||
|
a: &'a u32,
|
||||||
|
b: &'b NoCopyType
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main()
|
||||||
|
{
|
||||||
|
/* 'a tied to fn-main stackframe */
|
||||||
|
let var_a = 35;
|
||||||
|
let example: Example;
|
||||||
|
|
||||||
|
{
|
||||||
|
/* Lifetime 'b tied to new stackframe/scope */
|
||||||
|
let var_b = NoCopyType {};
|
||||||
|
|
||||||
|
/* fixme */
|
||||||
|
example = Example { a: &var_a, b: &var_b };
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("(Success!) {:?}", example);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct NoCopyType {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
struct Example<'a, 'b> {
|
||||||
|
a: &'a u32,
|
||||||
|
b: &'b NoCopyType
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fix function signature */
|
||||||
|
fn fix_me(foo: &Example) -> &NoCopyType
|
||||||
|
{ foo.b }
|
||||||
|
|
||||||
|
fn main()
|
||||||
|
{
|
||||||
|
let no_copy = NoCopyType {};
|
||||||
|
let example = Example { a: &1, b: &no_copy };
|
||||||
|
fix_me(&example);
|
||||||
|
println!("Success!")
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="method"><a class="header" href="#method">Method</a></h2>
|
||||||
|
<p>Methods are annotated similarly to functions.</p>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">struct Owner(i32);
|
||||||
|
|
||||||
|
impl Owner {
|
||||||
|
// Annotate lifetimes as in a standalone function.
|
||||||
|
fn add_one<'a>(&'a mut self) { self.0 += 1; }
|
||||||
|
fn print<'a>(&'a self) {
|
||||||
|
println!("`print`: {}", self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut owner = Owner(18);
|
||||||
|
|
||||||
|
owner.add_one();
|
||||||
|
owner.print();
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work by adding proper lifetime annotations */
|
||||||
|
struct ImportantExcerpt {
|
||||||
|
part: &str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImportantExcerpt {
|
||||||
|
fn level(&'a self) -> i32 {
|
||||||
|
3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}</code></pre></pre>
|
||||||
|
<h2 id="elision"><a class="header" href="#elision">Elision</a></h2>
|
||||||
|
<p>Some lifetime patterns are so common that borrow checker will allow you to omit them to save typing and improve readability.</p>
|
||||||
|
<p>This is known as <strong>Elision</strong>. Elision exist in Rust only because these patterns are common.</p>
|
||||||
|
<p>For a more comprehensive understanding of elision, please see <a href="https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-elision">lifetime elision</a> in the official book.</p>
|
||||||
|
<ol start="10">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Remove all the lifetimes that can be elided */
|
||||||
|
|
||||||
|
fn input<'a>(x: &'a i32) {
|
||||||
|
println!("`annotated_input`: {}", x);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pass<'a>(x: &'a i32) -> &'a i32 { x }
|
||||||
|
|
||||||
|
fn longest<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Owner(i32);
|
||||||
|
|
||||||
|
impl Owner {
|
||||||
|
// Annotate lifetimes as in a standalone function.
|
||||||
|
fn add_one<'a>(&'a mut self) { self.0 += 1; }
|
||||||
|
fn print<'a>(&'a self) {
|
||||||
|
println!("`print`: {}", self.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Person<'a> {
|
||||||
|
age: u8,
|
||||||
|
name: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Either<'a> {
|
||||||
|
Num(i32),
|
||||||
|
Ref(&'a i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/lifetime/basic.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../lifetime/intro.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="../lifetime/static.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="../lifetime/intro.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="../lifetime/static.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
229
lifetime/intro.html
Normal file
229
lifetime/intro.html
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Lifetime - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/lifetime/intro.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="lifetime"><a class="header" href="#lifetime">Lifetime</a></h1>
|
||||||
|
<p>Learning resources:</p>
|
||||||
|
<ul>
|
||||||
|
<li>English: <a href="https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html">Rust Book 10.3</a></li>
|
||||||
|
<li>简体中文: <a href="https://course.rs/advance/lifetime/intro.html">Rust语言圣经 - 生命周期</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../formatted-output/formatting.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="../lifetime/basic.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="../formatted-output/formatting.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="../lifetime/basic.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
405
lifetime/static.html
Normal file
405
lifetime/static.html
Normal file
@ -0,0 +1,405 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>&'static and T: 'static - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/lifetime/static.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="static-and-t-static"><a class="header" href="#static-and-t-static">&'static and T: 'static</a></h1>
|
||||||
|
<p><code>'static</code> is a reserved lifetime name, you might have encountered it several times:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>// A reference with 'static lifetime:
|
||||||
|
let s: &'static str = "hello world";
|
||||||
|
|
||||||
|
// 'static as part of a trait bound:
|
||||||
|
fn generic<T>(x: T) where T: 'static {}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>Though they are all <code>'static</code>, but subtly different.</p>
|
||||||
|
<h2 id="static"><a class="header" href="#static">&'static</a></h2>
|
||||||
|
<p>As a reference lifetime, <code>&'static</code> indicates the data pointed to by the reference lives as long as the running program. But it can still be coerced to a shorter lifetime.</p>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟 There are several ways to make a variable with <code>'static</code> lifetime, two of them are stored in the read-only memory of the binary.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
/* Fill in the blank in two ways */
|
||||||
|
fn main() {
|
||||||
|
__;
|
||||||
|
need_static(v);
|
||||||
|
|
||||||
|
println!("Success!")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn need_static(r : &'static str) {
|
||||||
|
assert_eq!(r, "hello");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟🌟🌟 Another way to make <code>'static</code> lifetime is using <code>Box::leak</code></li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">#[derive(Debug)]
|
||||||
|
struct Config {
|
||||||
|
a: String,
|
||||||
|
b: String,
|
||||||
|
}
|
||||||
|
static mut config: Option<&mut Config> = None;
|
||||||
|
|
||||||
|
/* Make it work without changing the function signatures of `init`*/
|
||||||
|
fn init() -> Option<&'static mut Config> {
|
||||||
|
Some(&mut Config {
|
||||||
|
a: "A".to_string(),
|
||||||
|
b: "B".to_string(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
unsafe {
|
||||||
|
config = init();
|
||||||
|
|
||||||
|
println!("{:?}",config)
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟 <code>&'static</code> only indicates that the data can live forever, not the reference. The latter one will be constrained by its scope.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">fn main() {
|
||||||
|
{
|
||||||
|
// Make a `string` literal and print it:
|
||||||
|
let static_string = "I'm in read-only memory";
|
||||||
|
println!("static_string: {}", static_string);
|
||||||
|
|
||||||
|
// When `static_string` goes out of scope, the reference
|
||||||
|
// can no longer be used, but the data remains in the binary.
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("static_string reference remains alive: {}", static_string);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li><code>&'static</code> can be coerced to a shorter lifetime.</li>
|
||||||
|
</ol>
|
||||||
|
<p><strong>Example</strong></p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// Make a constant with `'static` lifetime.
|
||||||
|
static NUM: i32 = 18;
|
||||||
|
|
||||||
|
// Returns a reference to `NUM` where its `'static`
|
||||||
|
// lifetime is coerced to that of the input argument.
|
||||||
|
fn coerce_static<'a>(_: &'a i32) -> &'a i32 {
|
||||||
|
&NUM
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
{
|
||||||
|
// Make an integer to use for `coerce_static`:
|
||||||
|
let lifetime_num = 9;
|
||||||
|
|
||||||
|
// Coerce `NUM` to lifetime of `lifetime_num`:
|
||||||
|
let coerced_static = coerce_static(&lifetime_num);
|
||||||
|
|
||||||
|
println!("coerced_static: {}", coerced_static);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("NUM: {} stays accessible!", NUM);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="t-static"><a class="header" href="#t-static">T: 'static</a></h2>
|
||||||
|
<p>As a trait bound, it means the type does not contain any non-static references. Eg. the receiver can hold on to the type for as long as they want and it will never become invalid until they drop it.</p>
|
||||||
|
<p>It's important to understand this means that any owned data always passes a <code>'static </code>lifetime bound, but a reference to that owned data generally does not.</p>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work */
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
fn print_it<T: Debug + 'static>( input: T) {
|
||||||
|
println!( "'static value passed in is: {:?}", input );
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_it1( input: impl Debug + 'static ) {
|
||||||
|
println!( "'static value passed in is: {:?}", input );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn print_it2<T: Debug + 'static>( input: &T) {
|
||||||
|
println!( "'static value passed in is: {:?}", input );
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// i is owned and contains no references, thus it's 'static:
|
||||||
|
let i = 5;
|
||||||
|
print_it(i);
|
||||||
|
|
||||||
|
// oops, &i only has the lifetime defined by the scope of
|
||||||
|
// main(), so it's not 'static:
|
||||||
|
print_it(&i);
|
||||||
|
|
||||||
|
print_it1(&i);
|
||||||
|
|
||||||
|
// but this one WORKS !
|
||||||
|
print_it2(&i);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::fmt::Display;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut string = "First".to_owned();
|
||||||
|
|
||||||
|
string.push_str(string.to_uppercase().as_str());
|
||||||
|
print_a(&string);
|
||||||
|
print_b(&string);
|
||||||
|
print_c(&string); // Compilation error
|
||||||
|
print_d(&string); // Compilation error
|
||||||
|
print_e(&string);
|
||||||
|
print_f(&string);
|
||||||
|
print_g(&string); // Compilation error
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_a<T: Display + 'static>(t: &T) {
|
||||||
|
println!("{}", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_b<T>(t: &T)
|
||||||
|
where
|
||||||
|
T: Display + 'static,
|
||||||
|
{
|
||||||
|
println!("{}", t);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_c(t: &'static dyn Display) {
|
||||||
|
println!("{}", t)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_d(t: &'static impl Display) {
|
||||||
|
println!("{}", t)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_e(t: &(dyn Display + 'static)) {
|
||||||
|
println!("{}", t)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_f(t: &(impl Display + 'static)) {
|
||||||
|
println!("{}", t)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_g(t: &'static String) {
|
||||||
|
println!("{}", t);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/lifetime/static.md">here</a>(under the solutions path), but only use it when you need it :)</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../lifetime/basic.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="../lifetime/advance.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="../lifetime/basic.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="../lifetime/advance.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
224
macro.html
Normal file
224
macro.html
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Macro TODO - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/macro.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="macro"><a class="header" href="#macro">macro</a></h1>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="unsafe/inline-asm.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="tests/intro.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="unsafe/inline-asm.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="tests/intro.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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
7
mark.min.js
vendored
Normal file
7
mark.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
480
method.html
Normal file
480
method.html
Normal file
@ -0,0 +1,480 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Method & Associated function - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/method.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="associated-functions--methods"><a class="header" href="#associated-functions--methods">Associated functions & Methods</a></h1>
|
||||||
|
<h2 id="examples"><a class="header" href="#examples">Examples</a></h2>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">struct Point {
|
||||||
|
x: f64,
|
||||||
|
y: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implementation block, all `Point` associated functions & methods go in here.
|
||||||
|
impl Point {
|
||||||
|
// This is an "associated function" because this function is associated with
|
||||||
|
// a particular type, that is, Point.
|
||||||
|
//
|
||||||
|
// Associated functions don't need to be called with an instance.
|
||||||
|
// These functions are generally used like constructors.
|
||||||
|
fn origin() -> Point {
|
||||||
|
Point { x: 0.0, y: 0.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Another associated function, taking two arguments:
|
||||||
|
fn new(x: f64, y: f64) -> Point {
|
||||||
|
Point { x: x, y: y }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Rectangle {
|
||||||
|
p1: Point,
|
||||||
|
p2: Point,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rectangle {
|
||||||
|
// This is a method.
|
||||||
|
// `&self` is sugar for `self: &Self`, where `Self` is the type of the
|
||||||
|
// caller object. In this case `Self` = `Rectangle`
|
||||||
|
fn area(&self) -> f64 {
|
||||||
|
// `self` gives access to the struct fields via the dot operator.
|
||||||
|
let Point { x: x1, y: y1 } = self.p1;
|
||||||
|
let Point { x: x2, y: y2 } = self.p2;
|
||||||
|
|
||||||
|
// `abs` is a `f64` method that returns the absolute value of the
|
||||||
|
// caller
|
||||||
|
((x1 - x2) * (y1 - y2)).abs()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn perimeter(&self) -> f64 {
|
||||||
|
let Point { x: x1, y: y1 } = self.p1;
|
||||||
|
let Point { x: x2, y: y2 } = self.p2;
|
||||||
|
|
||||||
|
2.0 * ((x1 - x2).abs() + (y1 - y2).abs())
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method requires the caller object to be mutable
|
||||||
|
// `&mut self` desugars to `self: &mut Self`
|
||||||
|
fn translate(&mut self, x: f64, y: f64) {
|
||||||
|
self.p1.x += x;
|
||||||
|
self.p2.x += x;
|
||||||
|
|
||||||
|
self.p1.y += y;
|
||||||
|
self.p2.y += y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// `Pair` owns resources: two heap allocated integers.
|
||||||
|
struct Pair(Box<i32>, Box<i32>);
|
||||||
|
|
||||||
|
impl Pair {
|
||||||
|
// This method "consumes" the resources of the caller object
|
||||||
|
// `self` desugars to `self: Self`
|
||||||
|
fn destroy(self) {
|
||||||
|
// Destructure `self`
|
||||||
|
let Pair(first, second) = self;
|
||||||
|
|
||||||
|
println!("Destroying Pair({}, {})", first, second);
|
||||||
|
|
||||||
|
// `first` and `second` go out of scope and get freed.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let rectangle = Rectangle {
|
||||||
|
// Associated functions are called using double colons
|
||||||
|
p1: Point::origin(),
|
||||||
|
p2: Point::new(3.0, 4.0),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Methods are called using the dot operator.
|
||||||
|
// Note that the first argument `&self` is implicitly passed, i.e.
|
||||||
|
// `rectangle.perimeter()` === `Rectangle::perimeter(&rectangle)`
|
||||||
|
println!("Rectangle perimeter: {}", rectangle.perimeter());
|
||||||
|
println!("Rectangle area: {}", rectangle.area());
|
||||||
|
|
||||||
|
let mut square = Rectangle {
|
||||||
|
p1: Point::origin(),
|
||||||
|
p2: Point::new(1.0, 1.0),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Error! `rectangle` is immutable, but this method requires a mutable
|
||||||
|
// object.
|
||||||
|
//rectangle.translate(1.0, 0.0);
|
||||||
|
// TODO ^ Try uncommenting this line
|
||||||
|
|
||||||
|
// Okay! Mutable objects can call mutable methods
|
||||||
|
square.translate(1.0, 1.0);
|
||||||
|
|
||||||
|
let pair = Pair(Box::new(1), Box::new(2));
|
||||||
|
|
||||||
|
pair.destroy();
|
||||||
|
|
||||||
|
// Error! Previous `destroy` call "consumed" `pair`
|
||||||
|
//pair.destroy();
|
||||||
|
// TODO ^ Try uncommenting this line
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="exercises"><a class="header" href="#exercises">Exercises</a></h2>
|
||||||
|
<h3 id="method"><a class="header" href="#method">Method</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟 Methods are similar to functions: Declare with <code>fn</code>, have parameters and a return value. Unlike functions, methods are defined within the context of a struct (or an enum or a trait object), and their first parameter is always <code>self</code>, which represents the instance of the struct the method is being called on.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">struct Rectangle {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rectangle {
|
||||||
|
// Complete the area method which return the area of a Rectangle.
|
||||||
|
fn area
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let rect1 = Rectangle { width: 30, height: 50 };
|
||||||
|
|
||||||
|
assert_eq!(rect1.area(), 1500);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟 <code>self</code> will take the ownership of current struct instance, however, <code>&self</code> will only borrow a reference from the instance.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// Only fill in the blanks, DON'T remove any line!
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct TrafficLight {
|
||||||
|
color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TrafficLight {
|
||||||
|
pub fn show_state(__) {
|
||||||
|
println!("the current state is {}", __.color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let light = TrafficLight{
|
||||||
|
color: "red".to_owned(),
|
||||||
|
};
|
||||||
|
// Don't take the ownership of `light` here.
|
||||||
|
light.show_state();
|
||||||
|
// ... Otherwise, there will be an error below
|
||||||
|
println!("{:?}", light);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟 The <code>&self</code> is actually short for <code>self: &Self</code>. Within an <code>impl</code> block, the type <code>Self</code> is an alias for the type that the <code>impl</code> block is for. Methods must have a parameter named <code>self</code> of type <code>Self</code> for their first parameter, so Rust lets you abbreviate this with only the name <code>self</code> in the first parameter spot.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">struct TrafficLight {
|
||||||
|
color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TrafficLight {
|
||||||
|
// Using `Self` to fill in the blank.
|
||||||
|
pub fn show_state(__) {
|
||||||
|
println!("the current state is {}", self.color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in the blank, DON'T use any variants of `Self`.
|
||||||
|
pub fn change_state(__) {
|
||||||
|
self.color = "green".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="associated-functions"><a class="header" href="#associated-functions">Associated functions</a></h3>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟 All functions defined within an <code>impl</code> block are called associated functions because they’re associated with the type named after the <code>impl</code>. We can define associated functions that don’t have <code>self</code> as their first parameter (and thus are not methods) because they don’t need an instance of the type to work with.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">#[derive(Debug)]
|
||||||
|
struct TrafficLight {
|
||||||
|
color: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TrafficLight {
|
||||||
|
// 1. Implement an associated function `new`,
|
||||||
|
// 2. It will return a TrafficLight contains color "red"
|
||||||
|
// 3. Must use `Self`, DONT use `TrafficLight` in fn signatures or body
|
||||||
|
pub fn new()
|
||||||
|
|
||||||
|
pub fn get_state(&self) -> &str {
|
||||||
|
&self.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let light = TrafficLight::new();
|
||||||
|
assert_eq!(light.get_state(), "red");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="multiple-impl-blocks"><a class="header" href="#multiple-impl-blocks">Multiple <code>impl</code> blocks</a></h3>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟 Each struct is allowed to have multiple impl blocks.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
struct Rectangle {
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Using multiple `impl` blocks to rewrite the code below.
|
||||||
|
impl Rectangle {
|
||||||
|
fn area(&self) -> u32 {
|
||||||
|
self.width * self.height
|
||||||
|
}
|
||||||
|
|
||||||
|
fn can_hold(&self, other: &Rectangle) -> bool {
|
||||||
|
self.width > other.width && self.height > other.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="enums"><a class="header" href="#enums">Enums</a></h3>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟🌟 We can also implement methods for enums.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum TrafficLightColor {
|
||||||
|
Red,
|
||||||
|
Yellow,
|
||||||
|
Green,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement TrafficLightColor with a method.
|
||||||
|
impl TrafficLightColor {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let c = TrafficLightColor::Yellow;
|
||||||
|
|
||||||
|
assert_eq!(c.color(), "yellow");
|
||||||
|
|
||||||
|
println!("{:?}",c);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="practice"><a class="header" href="#practice">Practice</a></h2>
|
||||||
|
<p>@todo</p>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="pattern-match/patterns.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="generics-traits/intro.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="pattern-match/patterns.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="generics-traits/intro.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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
7
mode-rust.js
Normal file
7
mode-rust.js
Normal file
File diff suppressed because one or more lines are too long
414
newtype-sized.html
Normal file
414
newtype-sized.html
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>newtype and DST - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/newtype-sized.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="newtype-and-sized"><a class="header" href="#newtype-and-sized">newtype and Sized</a></h1>
|
||||||
|
<h2 id="newtype"><a class="header" href="#newtype">Newtype</a></h2>
|
||||||
|
<p>The orphan rule tells us that we are allowed to implement a trait on a type as long as either the trait or the type are local to our crate.</p>
|
||||||
|
<p>The <strong>newtype pattern</strong> can help us get around this restriction, which involves creating a new type in a <strong>tuple struct</strong>.</p>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::fmt;
|
||||||
|
|
||||||
|
/* Define the Wrapper type */
|
||||||
|
__;
|
||||||
|
|
||||||
|
// Display is an external trait
|
||||||
|
impl fmt::Display for Wrapper {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "[{}]", self.0.join(", "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Vec is an external type, so you cannot implement Display trait on Vec type
|
||||||
|
let w = Wrapper(vec![String::from("hello"), String::from("world")]);
|
||||||
|
println!("w = {}", w);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟 Hide the methods of the original type.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it workd */
|
||||||
|
struct Meters(u32);
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let i: u32 = 2;
|
||||||
|
assert_eq!(i.pow(2), 4);
|
||||||
|
|
||||||
|
let n = Meters(i);
|
||||||
|
// The `pow` method is defined on `u32` type, we can't directly call it
|
||||||
|
assert_eq!(n.pow(2), 4);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟 The <code>newtype</code> idiom gives compile time guarantees that the right type of value is supplied to a program.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work */
|
||||||
|
struct Years(i64);
|
||||||
|
|
||||||
|
struct Days(i64);
|
||||||
|
|
||||||
|
impl Years {
|
||||||
|
pub fn to_days(&self) -> Days {
|
||||||
|
Days(self.0 * 365)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Days {
|
||||||
|
pub fn to_years(&self) -> Years {
|
||||||
|
Years(self.0 / 365)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// An age verification function that checks age in years, must be given a value of type Years.
|
||||||
|
fn old_enough(age: &Years) -> bool {
|
||||||
|
age.0 >= 18
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let age = Years(5);
|
||||||
|
let age_days = age.to_days();
|
||||||
|
println!("Old enough {}", old_enough(&age));
|
||||||
|
println!("Old enough {}", old_enough(&age_days));
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::ops::Add;
|
||||||
|
use std::fmt::{self, format};
|
||||||
|
|
||||||
|
struct Meters(u32);
|
||||||
|
impl fmt::Display for Meters {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "There are still {} meters left", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for Meters {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, other: Meters) -> Self {
|
||||||
|
Self(self.0 + other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let d = calculate_distance(Meters(10), Meters(20));
|
||||||
|
assert_eq!(format!("{}",d), "There are still 30 meters left");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implement calculate_distance */
|
||||||
|
fn calculate_distance</code></pre></pre>
|
||||||
|
<h2 id="type-alias"><a class="header" href="#type-alias">Type alias</a></h2>
|
||||||
|
<p>Type alias is important to improve the readability of our code.</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>type Thunk = Box<dyn Fn() + Send + 'static>;
|
||||||
|
|
||||||
|
let f: Thunk = Box::new(|| println!("hi"));
|
||||||
|
|
||||||
|
fn takes_long_type(f: Thunk) {
|
||||||
|
// --snip--
|
||||||
|
}
|
||||||
|
|
||||||
|
fn returns_long_type() -> Thunk {
|
||||||
|
// --snip--
|
||||||
|
}
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>type Result<T> = std::result::Result<T, std::io::Error>;
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<p>And Unlike newtype, type alias don't create new types, so the following code is valid:</p>
|
||||||
|
<pre><pre class="playground"><code class="language-rust edition2021"><span class="boring">#![allow(unused)]
|
||||||
|
</span><span class="boring">fn main() {
|
||||||
|
</span>type Meters = u32;
|
||||||
|
|
||||||
|
let x: u32 = 5;
|
||||||
|
let y: Meters = 5;
|
||||||
|
|
||||||
|
println!("x + y = {}", x + y);
|
||||||
|
<span class="boring">}</span></code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">enum VeryVerboseEnumOfThingsToDoWithNumbers {
|
||||||
|
Add,
|
||||||
|
Subtract,
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in the blank */
|
||||||
|
__
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// We can refer to each variant via its alias, not its long and inconvenient
|
||||||
|
// name.
|
||||||
|
let x = Operations::Add;
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟 There are a few preserved aliases in Rust, one of which can be used in <code>impl</code> blocks.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">enum VeryVerboseEnumOfThingsToDoWithNumbers {
|
||||||
|
Add,
|
||||||
|
Subtract,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl VeryVerboseEnumOfThingsToDoWithNumbers {
|
||||||
|
fn run(&self, x: i32, y: i32) -> i32 {
|
||||||
|
match self {
|
||||||
|
__::Add => x + y,
|
||||||
|
__::Subtract => x - y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h2 id="dst-and-unsized-type"><a class="header" href="#dst-and-unsized-type">DST and unsized type</a></h2>
|
||||||
|
<p>These concepts are complicated, so we are not going to explain here, but you can find them in <a href="https://doc.rust-lang.org/book/ch19-04-advanced-types.html?highlight=DST#dynamically-sized-types-and-the-sized-trait">The Book</a>.</p>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟🌟 Array with dynamic length is a Dynamic Sized Type ( DST ), we can't directly use it</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work with const generics */
|
||||||
|
fn my_function(n: usize) -> [u32; usize] {
|
||||||
|
[123; n]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let arr = my_function();
|
||||||
|
println!("{:?}",arr);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟🌟 Slice is unsized type, but the reference of slice is not.</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work with slice references */
|
||||||
|
fn main() {
|
||||||
|
let s: str = "Hello there!";
|
||||||
|
|
||||||
|
let arr: [u8] = [1, 2, 3];
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟🌟 Trait is also an unsized type</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">/* Make it work in two ways */
|
||||||
|
use std::fmt::Display;
|
||||||
|
fn foobar(thing: Display) {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}</code></pre></pre>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="functional-programing/iterator.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="smart-pointers/intro.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="functional-programing/iterator.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="smart-pointers/intro.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/custom3.js"></script>
|
||||||
|
<script src="assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
398
ownership/borrowing.html
Normal file
398
ownership/borrowing.html
Normal file
@ -0,0 +1,398 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Reference and Borrowing - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/ownership/borrowing.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="reference-and-borrowing"><a class="header" href="#reference-and-borrowing">Reference and Borrowing</a></h1>
|
||||||
|
<h3 id="reference"><a class="header" href="#reference">Reference</a></h3>
|
||||||
|
<ol>
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let x = 5;
|
||||||
|
// Fill the blank
|
||||||
|
let p = __;
|
||||||
|
|
||||||
|
println!("the memory address of x is {:p}", p); // One possible output: 0x16fa3ac84
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let x = 5;
|
||||||
|
let y = &x;
|
||||||
|
|
||||||
|
// Modify this line only
|
||||||
|
assert_eq!(5, y);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix error
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello, ");
|
||||||
|
|
||||||
|
borrow_object(s);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn borrow_object(s: &String) {}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Fix error
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello, ");
|
||||||
|
|
||||||
|
push_str(s);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn push_str(s: &mut String) {
|
||||||
|
s.push_str("world")
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello, ");
|
||||||
|
|
||||||
|
// Fill the blank to make it work
|
||||||
|
let p = __;
|
||||||
|
|
||||||
|
p.push_str("world");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="ref"><a class="header" href="#ref">Ref</a></h4>
|
||||||
|
<p><code>ref</code> can be used to take references to a value, similar to <code>&</code>.</p>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let c = '中';
|
||||||
|
|
||||||
|
let r1 = &c;
|
||||||
|
// Fill the blank,dont change other code
|
||||||
|
let __ r2 = c;
|
||||||
|
|
||||||
|
assert_eq!(*r1, *r2);
|
||||||
|
|
||||||
|
// Check the equality of the two address strings
|
||||||
|
assert_eq!(get_addr(r1),get_addr(r2));
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get memory address string
|
||||||
|
fn get_addr(r: &char) -> String {
|
||||||
|
format!("{:p}", r)
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="borrowing-rules"><a class="header" href="#borrowing-rules">Borrowing rules</a></h3>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Remove something to make it work
|
||||||
|
// Don't remove a whole line !
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello");
|
||||||
|
|
||||||
|
let r1 = &mut s;
|
||||||
|
let r2 = &mut s;
|
||||||
|
|
||||||
|
println!("{}, {}", r1, r2);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="mutability"><a class="header" href="#mutability">Mutability</a></h4>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟 Error: Borrow an immutable object as mutable</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// Fix error by modifying this line
|
||||||
|
let s = String::from("hello, ");
|
||||||
|
|
||||||
|
borrow_object(&mut s);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn borrow_object(s: &mut String) {}</code></pre></pre>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟🌟 Ok: Borrow a mutable object as immutable</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// This code has no errors!
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello, ");
|
||||||
|
|
||||||
|
borrow_object(&s);
|
||||||
|
|
||||||
|
s.push_str("world");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn borrow_object(s: &String) {}</code></pre></pre>
|
||||||
|
<h3 id="nll"><a class="header" href="#nll">NLL</a></h3>
|
||||||
|
<ol start="10">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// Comment one line to make it work
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello, ");
|
||||||
|
|
||||||
|
let r1 = &mut s;
|
||||||
|
r1.push_str("world");
|
||||||
|
let r2 = &mut s;
|
||||||
|
r2.push_str("!");
|
||||||
|
|
||||||
|
println!("{}",r1);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="11">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let mut s = String::from("hello, ");
|
||||||
|
|
||||||
|
let r1 = &mut s;
|
||||||
|
let r2 = &mut s;
|
||||||
|
|
||||||
|
// Add one line below to make a compiler error: cannot borrow `s` as mutable more than once at a time
|
||||||
|
// You can't use r1 and r2 at the same time
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/ownership/borrowing.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../ownership/ownership.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="../compound-types/intro.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="../ownership/ownership.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="../compound-types/intro.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
229
ownership/intro.html
Normal file
229
ownership/intro.html
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Ownership and Borrowing - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/ownership/intro.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="ownership-and-borrowing"><a class="header" href="#ownership-and-borrowing">Ownership and Borrowing</a></h1>
|
||||||
|
<p>Learning resources:</p>
|
||||||
|
<ul>
|
||||||
|
<li>English: <a href="https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html">Rust Book 4.1-4.4</a></li>
|
||||||
|
<li>简体中文: <a href="https://course.rs/basic/ownership/index.html">Rust语言圣经 - 所有权与借用</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../basic-types/functions.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="../ownership/ownership.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="../basic-types/functions.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="../ownership/ownership.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
377
ownership/ownership.html
Normal file
377
ownership/ownership.html
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Ownership - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/ownership/ownership.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="ownership"><a class="header" href="#ownership">Ownership</a></h1>
|
||||||
|
<ol>
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
// Use as many approaches as you can to make it work
|
||||||
|
let x = String::from("Hello world");
|
||||||
|
let y = x;
|
||||||
|
println!("{}, {}",x, y);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="2">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// Don't modify code in main!
|
||||||
|
fn main() {
|
||||||
|
let s1 = String::from("Hello world");
|
||||||
|
let s2 = take_ownership(s1);
|
||||||
|
|
||||||
|
println!("{}", s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only modify the code below!
|
||||||
|
fn take_ownership(s: String) {
|
||||||
|
println!("{}", s);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="3">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let s = give_ownership();
|
||||||
|
println!("{}", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only modify the code below!
|
||||||
|
fn give_ownership() -> String {
|
||||||
|
let s = String::from("Hello world");
|
||||||
|
// Convert String to Vec
|
||||||
|
let _s = s.into_bytes();
|
||||||
|
s
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="4">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// Fix the error without removing any code
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("Hello World");
|
||||||
|
|
||||||
|
print_str(s);
|
||||||
|
|
||||||
|
println!("{}", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_str(s: String) {
|
||||||
|
println!("{}",s)
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="5">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// Don't use clone ,use copy instead
|
||||||
|
fn main() {
|
||||||
|
let x = (1, 2, (), "hello".to_string());
|
||||||
|
let y = x.clone();
|
||||||
|
println!("{:?}, {:?}", x, y);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="mutability"><a class="header" href="#mutability">Mutability</a></h4>
|
||||||
|
<p>Mutability can be changed when ownership is transferred.</p>
|
||||||
|
<ol start="6">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
// make the necessary variable mutable
|
||||||
|
fn main() {
|
||||||
|
let s = String::from("Hello ");
|
||||||
|
|
||||||
|
let s1 = s;
|
||||||
|
|
||||||
|
s1.push_str("World!");
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="7">
|
||||||
|
<li>🌟🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let x = Box::new(5);
|
||||||
|
|
||||||
|
let ... // update this line, don't change other lines!
|
||||||
|
|
||||||
|
*y = 4;
|
||||||
|
|
||||||
|
assert_eq!(*x, 5);
|
||||||
|
|
||||||
|
println!("Success!");
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h3 id="partial-move"><a class="header" href="#partial-move">Partial move</a></h3>
|
||||||
|
<p>Within the destructuring of a single variable, both by-move and by-reference pattern bindings can be used at the same time. Doing this will result in a partial move of the variable, which means that parts of the variable will be moved while other parts stay. In such a case, the parent variable cannot be used afterwards as a whole, however the parts that are only referenced (and not moved) can still be used.</p>
|
||||||
|
<h4 id="example"><a class="header" href="#example">Example</a></h4>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Person {
|
||||||
|
name: String,
|
||||||
|
age: Box<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
let person = Person {
|
||||||
|
name: String::from("Alice"),
|
||||||
|
age: Box::new(20),
|
||||||
|
};
|
||||||
|
|
||||||
|
// `name` is moved out of person, but `age` is referenced
|
||||||
|
let Person { name, ref age } = person;
|
||||||
|
|
||||||
|
println!("The person's age is {}", age);
|
||||||
|
|
||||||
|
println!("The person's name is {}", name);
|
||||||
|
|
||||||
|
// Error! borrow of partially moved value: `person` partial move occurs
|
||||||
|
//println!("The person struct is {:?}", person);
|
||||||
|
|
||||||
|
// `person` cannot be used but `person.age` can be used as it is not moved
|
||||||
|
println!("The person's age from person struct is {}", person.age);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<h4 id="exercises"><a class="header" href="#exercises">Exercises</a></h4>
|
||||||
|
<ol start="8">
|
||||||
|
<li>🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let t = (String::from("hello"), String::from("world"));
|
||||||
|
|
||||||
|
let _s = t.0;
|
||||||
|
|
||||||
|
// Modify this line only, don't use `_s`
|
||||||
|
println!("{:?}", t);
|
||||||
|
}</code></pre></pre>
|
||||||
|
<ol start="9">
|
||||||
|
<li>🌟🌟</li>
|
||||||
|
</ol>
|
||||||
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||||
|
fn main() {
|
||||||
|
let t = (String::from("hello"), String::from("world"));
|
||||||
|
|
||||||
|
// Fill the blanks
|
||||||
|
let (__, __) = __;
|
||||||
|
|
||||||
|
println!("{:?}, {:?}, {:?}", s1, s2, t); // -> "hello", "world", ("hello", "world")
|
||||||
|
}</code></pre></pre>
|
||||||
|
<blockquote>
|
||||||
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/ownership/ownership.md">here</a>(under the solutions path), but only use it when you need it</p>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../ownership/intro.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="../ownership/borrowing.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="../ownership/intro.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="../ownership/borrowing.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
229
pattern-match/intro.html
Normal file
229
pattern-match/intro.html
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<!-- Book generated using mdBook -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Pattern Match - Rust By Practice</title>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Custom HTML head -->
|
||||||
|
|
||||||
|
<meta name="description" content="Learn Rust with Example, Exercise and real Practice, written with ❤️ by https://course.rs team">
|
||||||
|
<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/style1.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 By Practice</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-by-practice" 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-by-practice/edit/master/en/src/pattern-match/intro.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="pattern-match"><a class="header" href="#pattern-match">Pattern Match</a></h1>
|
||||||
|
<p>Learning resources:</p>
|
||||||
|
<ul>
|
||||||
|
<li>English: <a href="https://doc.rust-lang.org/book/ch18-00-patterns.html">Rust Book 18</a></li>
|
||||||
|
<li>简体中文: <a href="https://course.rs/basic/match-pattern/intro.html">Rust语言圣经 - 模式匹配</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||||
|
<!-- Mobile navigation buttons -->
|
||||||
|
<a rel="prev" href="../flow-control.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="../pattern-match/match-iflet.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="../flow-control.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="../pattern-match/match-iflet.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/custom3.js"></script>
|
||||||
|
<script src="../assets/lang1.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user