easy_rust/Chapter_57.html
2021-05-23 04:18:41 +00:00

418 lines
28 KiB
HTML

<!DOCTYPE HTML>
<html lang="en" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title> Crates and modules - Easy Rust</title>
<!-- Custom HTML head -->
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="">
<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" href="highlight.css">
<link rel="stylesheet" href="tomorrow-night.css">
<link rel="stylesheet" href="ayu-highlight.css">
<!-- Custom theme stylesheets -->
</head>
<body>
<!-- Provide site root to javascript -->
<script type="text/javascript">
var path_to_root = "";
var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "navy" : "light";
</script>
<!-- Work around some values being stored in localStorage wrapped in quotes -->
<script type="text/javascript">
try {
var theme = localStorage.getItem('mdbook-theme');
var 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 type="text/javascript">
var theme;
try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
if (theme === null || theme === undefined) { theme = default_theme; }
var html = document.querySelector('html');
html.classList.remove('no-js')
html.classList.remove('light')
html.classList.add(theme);
html.classList.add('js');
</script>
<!-- Hide / unhide sidebar before it is displayed -->
<script type="text/javascript">
var html = document.querySelector('html');
var sidebar = 'hidden';
if (document.body.clientWidth >= 1080) {
try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
sidebar = sidebar || 'visible';
}
html.classList.remove('sidebar-visible');
html.classList.add("sidebar-" + sidebar);
</script>
<nav id="sidebar" class="sidebar" aria-label="Table of contents">
<div class="sidebar-scrollbox">
<ol class="chapter"><li class="chapter-item expanded "><a href="Chapter_0.html"><strong aria-hidden="true">1.</strong> Updates</a></li><li class="chapter-item expanded "><a href="Chapter_1.html"><strong aria-hidden="true">2.</strong> Introduction</a></li><li class="chapter-item expanded "><a href="Chapter_2.html"><strong aria-hidden="true">3.</strong> Who am I?</a></li><li class="chapter-item expanded "><a href="Chapter_3.html"><strong aria-hidden="true">4.</strong> Writing Rust in Easy English</a></li><li class="chapter-item expanded "><a href="Chapter_4.html"><strong aria-hidden="true">5.</strong> Rust Playground</a></li><li class="chapter-item expanded "><a href="Chapter_5.html"><strong aria-hidden="true">6.</strong> 🚧 and ⚠️</a></li><li class="chapter-item expanded "><a href="Chapter_6.html"><strong aria-hidden="true">7.</strong> Comments</a></li><li class="chapter-item expanded "><a href="Chapter_7.html"><strong aria-hidden="true">8.</strong> Types</a></li><li class="chapter-item expanded "><a href="Chapter_8.html"><strong aria-hidden="true">9.</strong> Type inference</a></li><li class="chapter-item expanded "><a href="Chapter_9.html"><strong aria-hidden="true">10.</strong> Printing 'hello, world!'</a></li><li class="chapter-item expanded "><a href="Chapter_10.html"><strong aria-hidden="true">11.</strong> Display and debug</a></li><li class="chapter-item expanded "><a href="Chapter_11.html"><strong aria-hidden="true">12.</strong> Mutability (changing)</a></li><li class="chapter-item expanded "><a href="Chapter_12.html"><strong aria-hidden="true">13.</strong> The stack, the heap, and pointers</a></li><li class="chapter-item expanded "><a href="Chapter_13.html"><strong aria-hidden="true">14.</strong> More about printing</a></li><li class="chapter-item expanded "><a href="Chapter_14.html"><strong aria-hidden="true">15.</strong> Strings</a></li><li class="chapter-item expanded "><a href="Chapter_15.html"><strong aria-hidden="true">16.</strong> const and static</a></li><li class="chapter-item expanded "><a href="Chapter_16.html"><strong aria-hidden="true">17.</strong> More on references</a></li><li class="chapter-item expanded "><a href="Chapter_17.html"><strong aria-hidden="true">18.</strong> Mutable references</a></li><li class="chapter-item expanded "><a href="Chapter_18.html"><strong aria-hidden="true">19.</strong> Giving references to functions</a></li><li class="chapter-item expanded "><a href="Chapter_19.html"><strong aria-hidden="true">20.</strong> Copy types</a></li><li class="chapter-item expanded "><a href="Chapter_20.html"><strong aria-hidden="true">21.</strong> Collection types</a></li><li class="chapter-item expanded "><a href="Chapter_21.html"><strong aria-hidden="true">22.</strong> Vectors</a></li><li class="chapter-item expanded "><a href="Chapter_22.html"><strong aria-hidden="true">23.</strong> Tuples</a></li><li class="chapter-item expanded "><a href="Chapter_23.html"><strong aria-hidden="true">24.</strong> Control flow</a></li><li class="chapter-item expanded "><a href="Chapter_24.html"><strong aria-hidden="true">25.</strong> Structs</a></li><li class="chapter-item expanded "><a href="Chapter_25.html"><strong aria-hidden="true">26.</strong> Enums</a></li><li class="chapter-item expanded "><a href="Chapter_26.html"><strong aria-hidden="true">27.</strong> Loops</a></li><li class="chapter-item expanded "><a href="Chapter_27.html"><strong aria-hidden="true">28.</strong> Implementing structs and enums</a></li><li class="chapter-item expanded "><a href="Chapter_28.html"><strong aria-hidden="true">29.</strong> Destructuring</a></li><li class="chapter-item expanded "><a href="Chapter_29.html"><strong aria-hidden="true">30.</strong> References and the dot operator</a></li><li class="chapter-item expanded "><a href="Chapter_30.html"><strong aria-hidden="true">31.</strong> Generics</a></li><li class="chapter-item expanded "><a href="Chapter_31.html"><strong aria-hidden="true">32.</strong> Option and Result</a></li><li class="chapter-item expanded "><a href="Chapter_32.html"><strong aria-hidden="true">33.</strong> Other collections</a></li><li class="chapter-item expanded "><a href="Chapter_33.html"><strong aria-hidden="true">34.</strong> The ? operator</a></li><li class="chapter-item expanded "><a href="Chapter_34.html"><strong aria-hidden="true">35.</strong> Traits</a></li><li class="chapter-item expanded "><a href="Chapter_35.html"><strong aria-hidden="true">36.</strong> Chaining methods</a></li><li class="chapter-item expanded "><a href="Chapter_36.html"><strong aria-hidden="true">37.</strong> Iterators</a></li><li class="chapter-item expanded "><a href="Chapter_37.html"><strong aria-hidden="true">38.</strong> Closures</a></li><li class="chapter-item expanded "><a href="Chapter_38.html"><strong aria-hidden="true">39.</strong> The dbg! macro and .inspect</a></li><li class="chapter-item expanded "><a href="Chapter_39.html"><strong aria-hidden="true">40.</strong> Types of &amp;str</a></li><li class="chapter-item expanded "><a href="Chapter_40.html"><strong aria-hidden="true">41.</strong> Lifetimes</a></li><li class="chapter-item expanded "><a href="Chapter_41.html"><strong aria-hidden="true">42.</strong> Interior mutability</a></li><li class="chapter-item expanded "><a href="Chapter_42.html"><strong aria-hidden="true">43.</strong> Cow</a></li><li class="chapter-item expanded "><a href="Chapter_43.html"><strong aria-hidden="true">44.</strong> Type aliases</a></li><li class="chapter-item expanded "><a href="Chapter_44.html"><strong aria-hidden="true">45.</strong> The todo! macro</a></li><li class="chapter-item expanded "><a href="Chapter_45.html"><strong aria-hidden="true">46.</strong> Rc</a></li><li class="chapter-item expanded "><a href="Chapter_46.html"><strong aria-hidden="true">47.</strong> Multiple threads</a></li><li class="chapter-item expanded "><a href="Chapter_47.html"><strong aria-hidden="true">48.</strong> Closures in functions</a></li><li class="chapter-item expanded "><a href="Chapter_48.html"><strong aria-hidden="true">49.</strong> impl Trait</a></li><li class="chapter-item expanded "><a href="Chapter_49.html"><strong aria-hidden="true">50.</strong> Arc</a></li><li class="chapter-item expanded "><a href="Chapter_50.html"><strong aria-hidden="true">51.</strong> Channels</a></li><li class="chapter-item expanded "><a href="Chapter_51.html"><strong aria-hidden="true">52.</strong> Reading Rust documentation</a></li><li class="chapter-item expanded "><a href="Chapter_52.html"><strong aria-hidden="true">53.</strong> Attributes</a></li><li class="chapter-item expanded "><a href="Chapter_53.html"><strong aria-hidden="true">54.</strong> Box</a></li><li class="chapter-item expanded "><a href="Chapter_54.html"><strong aria-hidden="true">55.</strong> Box around traits</a></li><li class="chapter-item expanded "><a href="Chapter_55.html"><strong aria-hidden="true">56.</strong> Default and the builder pattern</a></li><li class="chapter-item expanded "><a href="Chapter_56.html"><strong aria-hidden="true">57.</strong> Deref and DerefMut</a></li><li class="chapter-item expanded "><a href="Chapter_57.html" class="active"><strong aria-hidden="true">58.</strong> Crates and modules</a></li><li class="chapter-item expanded "><a href="Chapter_58.html"><strong aria-hidden="true">59.</strong> Testing</a></li><li class="chapter-item expanded "><a href="Chapter_59.html"><strong aria-hidden="true">60.</strong> External crates</a></li><li class="chapter-item expanded "><a href="Chapter_60.html"><strong aria-hidden="true">61.</strong> A tour of the standard library</a></li><li class="chapter-item expanded "><a href="Chapter_61.html"><strong aria-hidden="true">62.</strong> Writing macros</a></li><li class="chapter-item expanded "><a href="Chapter_62.html"><strong aria-hidden="true">63.</strong> cargo</a></li><li class="chapter-item expanded "><a href="Chapter_63.html"><strong aria-hidden="true">64.</strong> Taking user input</a></li><li class="chapter-item expanded "><a href="Chapter_64.html"><strong aria-hidden="true">65.</strong> Using files</a></li><li class="chapter-item expanded "><a href="Chapter_65.html"><strong aria-hidden="true">66.</strong> cargo doc</a></li><li class="chapter-item expanded "><a href="Chapter_66.html"><strong aria-hidden="true">67.</strong> The end?</a></li></ol>
</div>
<div id="sidebar-resize-handle" class="sidebar-resize-handle"></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 bordered">
<div class="left-buttons">
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
<i class="fa fa-bars"></i>
</button>
<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="light">Light (default)</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">Easy Rust</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>
</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 type="text/javascript">
document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="content" class="content">
<main>
<h2 id="crates-and-modules"><a class="header" href="#crates-and-modules">Crates and modules</a></h2>
<p>Every time you write code in Rust, you are writing it in a <code>crate</code>. A <code>crate</code> is the file, or files, that go together for your code. Inside the file you write you can also make a <code>mod</code>. A <code>mod</code> is a space for functions, structs, etc. and is used for a few reasons:</p>
<ul>
<li>Building your code: it helps you think about the general structure of your code. This can be important as your code gets larger and larger.</li>
<li>Reading your code: people can understand your code more easily. For example, the name <code>std::collections::HashMap</code> tells you that it's in <code>std</code> inside the module <code>collections</code>. This gives you a hint that maybe there are more collection types inside <code>collections</code> that you can try.</li>
<li>Privacy: everything starts out as private. That lets you keep users from using functions directly.</li>
</ul>
<p>To make a <code>mod</code>, just write <code>mod</code> and start a code block with <code>{}</code>. We will make a mod called <code>print_things</code> that has some printing-related functions.</p>
<pre><pre class="playground"><code class="language-rust">mod print_things {
use std::fmt::Display;
fn prints_one_thing&lt;T: Display&gt;(input: T) { // Print anything that implements Display
println!(&quot;{}&quot;, input)
}
}
fn main() {}
</code></pre></pre>
<p>You can see that we wrote <code>use std::fmt::Display;</code> inside <code>print_things</code>, because it is a separate space. If you wrote <code>use std::fmt::Display;</code> inside <code>main()</code> it wouldn't help. Also, we can't call it from <code>main()</code> right now. Without the <code>pub</code> keyword in front of <code>fn</code> it will stay private. Let's try to call it without <code>pub</code>. Here's one way to write it:</p>
<pre><pre class="playground"><code class="language-rust">// 🚧
fn main() {
crate::print_things::prints_one_thing(6);
}
</code></pre></pre>
<p><code>crate</code> means &quot;inside this project&quot;, but for our simple example it's the same as &quot;inside this file&quot;. Inside that is the mod <code>print_things</code>, then finally the <code>prints_one_thing()</code> function. You can write that every time, or you can write <code>use</code> to import it. Now we can see the error that says that it's private:</p>
<pre><pre class="playground"><code class="language-rust">// ⚠️
mod print_things {
use std::fmt::Display;
fn prints_one_thing&lt;T: Display&gt;(input: T) {
println!(&quot;{}&quot;, input)
}
}
fn main() {
use crate::print_things::prints_one_thing;
prints_one_thing(6);
prints_one_thing(&quot;Trying to print a string...&quot;.to_string());
}
</code></pre></pre>
<p>Here's the error:</p>
<pre><code class="language-text">error[E0603]: function `prints_one_thing` is private
--&gt; src\main.rs:10:30
|
10 | use crate::print_things::prints_one_thing;
| ^^^^^^^^^^^^^^^^ private function
|
note: the function `prints_one_thing` is defined here
--&gt; src\main.rs:4:5
|
4 | fn prints_one_thing&lt;T: Display&gt;(input: T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
</code></pre>
<p>It's easy to understand that function <code>print_one_thing</code> is private. It also shows us with <code>src\main.rs:4:5</code> where to find the function. This is helpful because you can write <code>mod</code>s not just in one file, but over a lot of files as well.</p>
<p>Now we just write <code>pub fn</code> instead of <code>fn</code> and everything works.</p>
<pre><pre class="playground"><code class="language-rust">mod print_things {
use std::fmt::Display;
pub fn prints_one_thing&lt;T: Display&gt;(input: T) {
println!(&quot;{}&quot;, input)
}
}
fn main() {
use crate::print_things::prints_one_thing;
prints_one_thing(6);
prints_one_thing(&quot;Trying to print a string...&quot;.to_string());
}
</code></pre></pre>
<p>This prints:</p>
<pre><code class="language-text">6
Trying to print a string...
</code></pre>
<p>How about <code>pub</code> for a struct, enum, trait, or module? <code>pub</code> works like this for them:</p>
<ul>
<li><code>pub</code> for a struct: it makes the struct public, but the items are not public. To make an item public, you have to write <code>pub</code> for each one too.</li>
<li><code>pub</code> for an enum or trait: everything becomes public. This makes sense because traits are about giving the same behaviour to something. And enums are about choosing between items, and you need to see them all to choose them.</li>
<li><code>pub</code> for a module: a top level module will be <code>pub</code> because if it isn't pub then nobody can touch anything in it at all. But modules inside modules need <code>pub</code> to be public.</li>
</ul>
<p>So let's put a struct named <code>Billy</code> inside <code>print_things</code>. This struct will be almost all public, but not quite. The struct is public so it will say <code>pub struct Billy</code>. Inside it will have a <code>name</code> and <code>times_to_print</code>. <code>name</code> will not be public, because we only want the user to create structs named <code>&quot;Billy&quot;.to_string()</code>. But the user can select the number of times to print, so that will be public. It looks like this:</p>
<pre><pre class="playground"><code class="language-rust">mod print_things {
use std::fmt::{Display, Debug};
#[derive(Debug)]
pub struct Billy { // Billy is public
name: String, // but name is private.
pub times_to_print: u32,
}
impl Billy {
pub fn new(times_to_print: u32) -&gt; Self { // That means the user needs to use new to create a Billy. The user can only change the number of times_to_print
Self {
name: &quot;Billy&quot;.to_string(), // We choose the name - the user can't
times_to_print,
}
}
pub fn print_billy(&amp;self) { // This function prints a Billy
for _ in 0..self.times_to_print {
println!(&quot;{:?}&quot;, self.name);
}
}
}
pub fn prints_one_thing&lt;T: Display&gt;(input: T) {
println!(&quot;{}&quot;, input)
}
}
fn main() {
use crate::print_things::*; // Now we use *. This imports everything from print_things
let my_billy = Billy::new(3);
my_billy.print_billy();
}
</code></pre></pre>
<p>This will print:</p>
<pre><code class="language-text">&quot;Billy&quot;
&quot;Billy&quot;
&quot;Billy&quot;
</code></pre>
<p>By the way, the <code>*</code> to import everything is called the &quot;glob operator&quot;. Glob means &quot;global&quot;, so it means everything.</p>
<p>Inside a <code>mod</code> you can create other mods. A child mod (a mod inside of a mod) can always use anything inside a parent mod. You can see this in the next example where we have a <code>mod city</code> inside a <code>mod province</code> inside a <code>mod country</code>.</p>
<p>You can think of the structure like this: even if you are in a country, you might not be in a province. And even if you are in a province, you might not be in a city. But if you are in a city, you are in its province and you are in its country.</p>
<pre><pre class="playground"><code class="language-rust">mod country { // The main mod doesn't need pub
fn print_country(country: &amp;str) { // Note: this function isn't public
println!(&quot;We are in the country of {}&quot;, country);
}
pub mod province { // Make this mod public
fn print_province(province: &amp;str) { // Note: this function isn't public
println!(&quot;in the province of {}&quot;, province);
}
pub mod city { // Make this mod public
pub fn print_city(country: &amp;str, province: &amp;str, city: &amp;str) { // This function is public though
crate::country::print_country(country);
crate::country::province::print_province(province);
println!(&quot;in the city of {}&quot;, city);
}
}
}
}
fn main() {
crate::country::province::city::print_city(&quot;Canada&quot;, &quot;New Brunswick&quot;, &quot;Moncton&quot;);
}
</code></pre></pre>
<p>The interesting part is that <code>print_city</code> can access <code>print_province</code> and <code>print_country</code>. That's because <code>mod city</code> is inside the other mods. It doesn't need <code>pub</code> in front of <code>print_province</code> to use it. And that makes sense: a city doesn't need to do anything to be inside a province and inside a country.</p>
<p>You probably noticed that <code>crate::country::province::print_province(province);</code> is very long. When we are inside a module we can use <code>super</code> to bring in items from above. Actually the word super itself means &quot;above&quot;, like in &quot;superior&quot;. In our example we only used the function once, but if you use it more then it is a good idea to import. It can also be a good idea if it makes your code easier to read, even if you only use the function once. The code is almost the same now, but a bit easier to read:</p>
<pre><pre class="playground"><code class="language-rust">mod country {
fn print_country(country: &amp;str) {
println!(&quot;We are in the country of {}&quot;, country);
}
pub mod province {
fn print_province(province: &amp;str) {
println!(&quot;in the province of {}&quot;, province);
}
pub mod city {
use super::super::*; // use everything in &quot;above above&quot;: that means mod country
use super::*; // use everything in &quot;above&quot;: that means mod province
pub fn print_city(country: &amp;str, province: &amp;str, city: &amp;str) {
print_country(country);
print_province(province);
println!(&quot;in the city of {}&quot;, city);
}
}
}
}
fn main() {
use crate::country::province::city::print_city; // bring in the function
print_city(&quot;Canada&quot;, &quot;New Brunswick&quot;, &quot;Moncton&quot;);
print_city(&quot;Korea&quot;, &quot;Gyeonggi-do&quot;, &quot;Gwangju&quot;); // Now it's less work to use it again
}
</code></pre></pre>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="Chapter_56.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" href="Chapter_58.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="Chapter_56.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" href="Chapter_58.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 type="text/javascript">
window.playground_copyable = true;
</script>
<script src="elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
<script src="mark.min.js" type="text/javascript" charset="utf-8"></script>
<script src="searcher.js" type="text/javascript" charset="utf-8"></script>
<script src="clipboard.min.js" type="text/javascript" charset="utf-8"></script>
<script src="highlight.js" type="text/javascript" charset="utf-8"></script>
<script src="book.js" type="text/javascript" charset="utf-8"></script>
<!-- Custom JS scripts -->
</body>
</html>