mirror of
https://github.com/sunface/rust-by-practice.git
synced 2025-06-23 04:29:41 +00:00
328 lines
15 KiB
HTML
328 lines
15 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en" class="light sidebar-visible" dir="ltr">
|
|
<head>
|
|
<!-- Book generated using mdBook -->
|
|
<meta charset="UTF-8">
|
|
<title>panic! - 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/result-panic/panic.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="panic"><a class="header" href="#panic">panic!</a></h1>
|
|
<p>The simplest error handling mechanism is to use <code>panic</code>. It just prints an error message and starts unwinding the stack, finally exit the current thread:</p>
|
|
<ul>
|
|
<li>if panic occurred in <code>main</code> thread, then the program will be exited.</li>
|
|
<li>if in spawned thread, then this thread will be terminated, but the program won't</li>
|
|
</ul>
|
|
<ol>
|
|
<li>🌟🌟</li>
|
|
</ol>
|
|
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
|
// FILL the blanks
|
|
fn drink(beverage: &str) {
|
|
if beverage == "lemonade" {
|
|
println!("Success!");
|
|
// IMPLEMENT the below code
|
|
__
|
|
}
|
|
|
|
println!("Exercise Failed if printing out this line!");
|
|
}
|
|
|
|
fn main() {
|
|
drink(__);
|
|
|
|
println!("Exercise Failed if printing out this line!");
|
|
}</code></pre></pre>
|
|
<h2 id="common-panic-cases"><a class="header" href="#common-panic-cases">common panic cases</a></h2>
|
|
<ol start="2">
|
|
<li>🌟🌟</li>
|
|
</ol>
|
|
<pre><pre class="playground"><code class="language-rust editable edition2021">// MAKE the code work by fixing all panics
|
|
fn main() {
|
|
assert_eq!("abc".as_bytes(), [96, 97, 98]);
|
|
|
|
let v = vec![1, 2, 3];
|
|
let ele = v[3];
|
|
// unwrap may panic when get return a None
|
|
let ele = v.get(3).unwrap();
|
|
|
|
// Sometimes, the compiler is unable to find the overflow errors for you in compile time ,so a panic will occur
|
|
let v = production_rate_per_hour(2);
|
|
|
|
// because of the same reason as above, we have to wrap it in a function to make the panic occur
|
|
divide(15, 0);
|
|
|
|
println!("Success!")
|
|
}
|
|
|
|
fn divide(x:u8, y:u8) {
|
|
println!("{}", x / y)
|
|
}
|
|
|
|
fn production_rate_per_hour(speed: u8) -> f64 {
|
|
let cph: u8 = 221;
|
|
match speed {
|
|
1..=4 => (speed * cph) as f64,
|
|
5..=8 => (speed * cph) as f64 * 0.9,
|
|
9..=10 => (speed * cph) as f64 * 0.77,
|
|
_ => 0 as f64,
|
|
}
|
|
}
|
|
|
|
pub fn working_items_per_minute(speed: u8) -> u32 {
|
|
(production_rate_per_hour(speed) / 60 as f64) as u32
|
|
}</code></pre></pre>
|
|
<h3 id="detailed-call-stack"><a class="header" href="#detailed-call-stack">Detailed call stack</a></h3>
|
|
<p>By default the stack unwinding will only give something like this:</p>
|
|
<pre><code class="language-shell">thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 99', src/main.rs:4:5
|
|
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
|
</code></pre>
|
|
<p>Though there is the reason of panic and the line of the code is showing where the panic has occured, sometimes we want to get more info about the call stack.</p>
|
|
<ol start="3">
|
|
<li>🌟</li>
|
|
</ol>
|
|
<pre><code class="language-shell">## FILL in the blank to display the whole call stack
|
|
## Tips: you can find the clue in the default panic info
|
|
$ __ cargo run
|
|
thread 'main' panicked at 'assertion failed: `(left == right)`
|
|
left: `[97, 98, 99]`,
|
|
right: `[96, 97, 98]`', src/main.rs:3:5
|
|
stack backtrace:
|
|
0: rust_begin_unwind
|
|
at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/std/src/panicking.rs:498:5
|
|
1: core::panicking::panic_fmt
|
|
at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/core/src/panicking.rs:116:14
|
|
2: core::panicking::assert_failed_inner
|
|
3: core::panicking::assert_failed
|
|
at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/core/src/panicking.rs:154:5
|
|
4: study_cargo::main
|
|
at ./src/main.rs:3:5
|
|
5: core::ops::function::FnOnce::call_once
|
|
at /rustc/9d1b2106e23b1abd32fce1f17267604a5102f57a/library/core/src/ops/function.rs:227:5
|
|
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
|
|
</code></pre>
|
|
<h3 id="unwinding-and-abort"><a class="header" href="#unwinding-and-abort"><code>unwinding</code> and <code>abort</code></a></h3>
|
|
<p>By default, when a <code>panic</code> occurs, the program starts <em>unwinding</em>, which means Rust walks back up the stack and cleans up the data from each function it encounters.</p>
|
|
<p>But this walk back and clean up is a lot of work. The alternative is to immediately abort the program without cleaning up.</p>
|
|
<p>If in your project you need to make the resulting binary as small as possible, you can switch from unwinding to aborting by adding below content to <code>Cargo.toml</code>:</p>
|
|
<pre><code class="language-toml">[profile.release]
|
|
panic = 'abort'
|
|
</code></pre>
|
|
<blockquote>
|
|
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/result-panic/panic.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="../result-panic/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="../result-panic/result.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/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="../result-panic/result.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>
|