mirror of
https://github.com/sunface/rust-by-practice.git
synced 2025-08-13 23:14:45 +00:00
deploy
This commit is contained in:
229
result-panic/intro.html
Normal file
229
result-panic/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>Result and 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/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="result-and-panic"><a class="header" href="#result-and-panic">Result and panic</a></h1>
|
||||
<p>Learning resources:</p>
|
||||
<ul>
|
||||
<li>English: <a href="https://doc.rust-lang.org/book/ch09-00-error-handling.html">Rust Book 9.1, 9.2</a></li>
|
||||
<li>简体中文: <a href="https://course.rs/basic/result-error/intro.html">Rust语言圣经 - 返回值和错误处理</a></li>
|
||||
</ul>
|
||||
|
||||
</main>
|
||||
|
||||
<nav class="nav-wrapper" aria-label="Page navigation">
|
||||
<!-- Mobile navigation buttons -->
|
||||
<a rel="prev" href="../type-conversions/others.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/panic.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="../type-conversions/others.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/panic.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>
|
327
result-panic/panic.html
Normal file
327
result-panic/panic.html
Normal file
@@ -0,0 +1,327 @@
|
||||
<!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>
|
420
result-panic/result.html
Normal file
420
result-panic/result.html
Normal file
@@ -0,0 +1,420 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html lang="en" class="light sidebar-visible" dir="ltr">
|
||||
<head>
|
||||
<!-- Book generated using mdBook -->
|
||||
<meta charset="UTF-8">
|
||||
<title>Result and ? - 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/result.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="result-and-"><a class="header" href="#result-and-">result and ?</a></h1>
|
||||
<p><code>Result<T></code> is an enum to describe possible errors. It has two variants:</p>
|
||||
<ul>
|
||||
<li><code>Ok(T)</code>: A value T was found</li>
|
||||
<li><code>Err(e)</code>: An error was found with a value <code>e</code></li>
|
||||
</ul>
|
||||
<p>In short words, the expected outcome is <code>Ok</code>, while the unexpected outcome is <code>Err</code>.</p>
|
||||
<ol>
|
||||
<li>🌟🌟</li>
|
||||
</ol>
|
||||
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||
// FILL in the blanks and FIX the errors
|
||||
use std::num::ParseIntError;
|
||||
|
||||
fn multiply(n1_str: &str, n2_str: &str) -> __ {
|
||||
let n1 = n1_str.parse::<i32>();
|
||||
let n2 = n2_str.parse::<i32>();
|
||||
Ok(n1.unwrap() * n2.unwrap())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let result = multiply("10", "2");
|
||||
assert_eq!(result, __);
|
||||
|
||||
let result = multiply("t", "2");
|
||||
assert_eq!(result.__, 8);
|
||||
|
||||
println!("Success!");
|
||||
}</code></pre></pre>
|
||||
<h3 id=""><a class="header" href="#">?</a></h3>
|
||||
<p><code>?</code> is almost exactly equivalent to <code>unwrap</code>, but <code>?</code> returns instead of panic on <code>Err</code>.</p>
|
||||
<ol start="2">
|
||||
<li>🌟🌟</li>
|
||||
</ol>
|
||||
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||
use std::num::ParseIntError;
|
||||
|
||||
// IMPLEMENT multiply with ?
|
||||
// DON'T use unwrap here
|
||||
fn multiply(n1_str: &str, n2_str: &str) -> __ {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(multiply("3", "4").unwrap(), 12);
|
||||
println!("Success!");
|
||||
}</code></pre></pre>
|
||||
<ol start="3">
|
||||
<li>🌟🌟</li>
|
||||
</ol>
|
||||
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read};
|
||||
|
||||
fn read_file1() -> Result<String, io::Error> {
|
||||
let f = File::open("hello.txt");
|
||||
let mut f = match f {
|
||||
Ok(file) => file,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
let mut s = String::new();
|
||||
match f.read_to_string(&mut s) {
|
||||
Ok(_) => Ok(s),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
// FILL in the blanks with one code line
|
||||
// DON'T change any code lines
|
||||
fn read_file2() -> Result<String, io::Error> {
|
||||
let mut s = String::new();
|
||||
|
||||
__;
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(read_file1().unwrap_err().to_string(), read_file2().unwrap_err().to_string());
|
||||
println!("Success!");
|
||||
}</code></pre></pre>
|
||||
<h3 id="map--and_then"><a class="header" href="#map--and_then">map & and_then</a></h3>
|
||||
<p><a href="https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.map">map</a> and <a href="https://doc.rust-lang.org/stable/std/result/enum.Result.html#method.and_then">and_then</a> are two common combinators for <code>Result<T, E></code> (also for <code>Option<T></code>).</p>
|
||||
<ol start="4">
|
||||
<li>🌟🌟</li>
|
||||
</ol>
|
||||
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::num::ParseIntError;
|
||||
|
||||
// FILL in the blank in two ways: map, and then
|
||||
fn add_two(n_str: &str) -> Result<i32, ParseIntError> {
|
||||
n_str.parse::<i32>().__
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(add_two("4").unwrap(), 6);
|
||||
|
||||
println!("Success!");
|
||||
}</code></pre></pre>
|
||||
<ol start="5">
|
||||
<li>🌟🌟🌟</li>
|
||||
</ol>
|
||||
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::num::ParseIntError;
|
||||
|
||||
// With the return type rewritten, we use pattern matching without `unwrap()`.
|
||||
// But it's so Verbose...
|
||||
fn multiply(n1_str: &str, n2_str: &str) -> Result<i32, ParseIntError> {
|
||||
match n1_str.parse::<i32>() {
|
||||
Ok(n1) => {
|
||||
match n2_str.parse::<i32>() {
|
||||
Ok(n2) => {
|
||||
Ok(n1 * n2)
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
},
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
// Rewriting `multiply` to make it succinct
|
||||
// You should use BOTH of `and_then` and `map` here.
|
||||
fn multiply1(n1_str: &str, n2_str: &str) -> Result<i32, ParseIntError> {
|
||||
// IMPLEMENT...
|
||||
}
|
||||
|
||||
fn print(result: Result<i32, ParseIntError>) {
|
||||
match result {
|
||||
Ok(n) => println!("n is {}", n),
|
||||
Err(e) => println!("Error: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// This still presents a reasonable answer.
|
||||
let twenty = multiply1("10", "2");
|
||||
print(twenty);
|
||||
|
||||
// The following now provides a much more helpful error message.
|
||||
let tt = multiply("t", "2");
|
||||
print(tt);
|
||||
|
||||
println!("Success!");
|
||||
}</code></pre></pre>
|
||||
<h3 id="type-alias"><a class="header" href="#type-alias">Type alias</a></h3>
|
||||
<p>Using <code>std::result::Result<T, ParseIntError></code> everywhere is verbose and tedious, we can use alias for this purpose.</p>
|
||||
<p>At a module level, creating aliases can be particularly helpful. Errors found in a specific module often has the same <code>Err</code> type, so a single alias can succinctly defined all associated <code>Results</code>. This is so useful even the <code>std</code> library supplies one: <a href="https://doc.rust-lang.org/std/io/type.Result.html"><code>io::Result</code></a>.</p>
|
||||
<ol start="6">
|
||||
<li>🌟</li>
|
||||
</ol>
|
||||
<pre><pre class="playground"><code class="language-rust editable edition2021">use std::num::ParseIntError;
|
||||
|
||||
// FILL in the blank
|
||||
type __;
|
||||
|
||||
// Use the above alias to refer to our specific `Result` type.
|
||||
fn multiply(first_number_str: &str, second_number_str: &str) -> Res<i32> {
|
||||
first_number_str.parse::<i32>().and_then(|first_number| {
|
||||
second_number_str.parse::<i32>().map(|second_number| first_number * second_number)
|
||||
})
|
||||
}
|
||||
|
||||
// Here, the alias again allows us to save some space.
|
||||
fn print(result: Res<i32>) {
|
||||
match result {
|
||||
Ok(n) => println!("n is {}", n),
|
||||
Err(e) => println!("Error: {}", e),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
print(multiply("10", "2"));
|
||||
print(multiply("t", "2"));
|
||||
|
||||
println!("Success!");
|
||||
}</code></pre></pre>
|
||||
<h3 id="using-result-in-fn-main"><a class="header" href="#using-result-in-fn-main">Using Result in <code>fn main</code></a></h3>
|
||||
<p>Typically <code>the</code> main function will look like this:</p>
|
||||
<pre><pre class="playground"><code class="language-rust edition2021">fn main() {
|
||||
println!("Hello World!");
|
||||
}</code></pre></pre>
|
||||
<p>However <code>main</code> is also able to have a return type of <code>Result</code>. If an error occurs within the <code>main</code> function it will return an error code and print a debug representation of the error( Debug trait ).</p>
|
||||
<p>The following example shows such a scenario:</p>
|
||||
<pre><pre class="playground"><code class="language-rust editable edition2021">
|
||||
use std::num::ParseIntError;
|
||||
|
||||
fn main() -> Result<(), ParseIntError> {
|
||||
let number_str = "10";
|
||||
let number = match number_str.parse::<i32>() {
|
||||
Ok(number) => number,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
println!("{}", number);
|
||||
Ok(())
|
||||
}</code></pre></pre>
|
||||
<blockquote>
|
||||
<p>You can find the solutions <a href="https://github.com/sunface/rust-by-practice/blob/master/solutions/result-panic/result.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/panic.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../crate-module/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="../result-panic/panic.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
</a>
|
||||
|
||||
<a rel="next prefetch" href="../crate-module/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>
|
Reference in New Issue
Block a user