Files
rust-by-practice/collections/vector.html
sunface 987c59ed75 deploy
2025-04-25 12:48:03 +08:00

452 lines
18 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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(&amp;v);
let v = vec![1, 2, 3];
is_vec(&amp;v);
// vec!(..) and vec![..] are same macros, so
let v = vec!(1, 2, 3);
is_vec(&amp;v);
// In code below, v is Vec&lt;[u8; 3]&gt; , not Vec&lt;u8&gt;
// USE Vec::new and `for` to rewrite the below code
let v1 = vec!(arr);
is_vec(&amp;v1);
assert_eq!(v, v1);
println!("Success!");
}
fn is_vec(v: &amp;Vec&lt;u8&gt;) {}</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 -&gt; Vec
// impl From&lt;[T; N]&gt; for Vec
let arr = [1, 2, 3];
let v1 = __(arr);
let v2: Vec&lt;i32&gt; = arr.__();
assert_eq!(v1, v2);
// String -&gt; Vec
// impl From&lt;String&gt; for Vec
let s = "hello".to_string();
let v1: Vec&lt;u8&gt; = s.__();
let s = "hello".to_string();
let v2 = s.into_bytes();
assert_eq!(v1, v2);
// impl&lt;'_&gt; From&lt;&amp;'_ str&gt; for Vec
let s = "hello";
let v3 = Vec::__(s);
assert_eq!(v2, v3);
// Iterators can be collected into vectors
let v4: Vec&lt;i32&gt; = [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>&amp;</code> or <code>&amp;mut</code>, respectively.</p>
<p>In Rust, its 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>&amp;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 = &amp;v[..];
// Out of bounds will cause a panic
// You must use `v.len` here
let slice2 = &amp;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 &amp;Vec are different
let vec_ref: &amp;mut Vec&lt;i32&gt; = &amp;mut v;
(*vec_ref).push(4);
let slice3 = &amp;mut v[0..3];
slice3[3] = 42;
assert_eq!(slice3, &amp;[1, 2, 3, 42]);
assert_eq!(v, &amp;[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 vectors 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 vectors 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() &gt;= 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&lt;IpAddr&gt;= __;
// 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(&amp;self);
}
struct V4(String);
impl IpAddr for V4 {
fn display(&amp;self) {
println!("ipv4: {:?}",self.0)
}
}
struct V6(String);
impl IpAddr for V6 {
fn display(&amp;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>