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:
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>
|
Reference in New Issue
Block a user