build: 2026-06-22

This commit is contained in:
2026-06-22 21:17:36 +05:30
commit dbddc0ce2d
202 changed files with 97026 additions and 0 deletions

View File

@@ -0,0 +1,632 @@
<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Defining an Enum - The Rust Programming Language</title>
<!-- Custom HTML head -->
<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-de23e50b.svg">
<link rel="shortcut icon" href="favicon-8114d1fc.png">
<link rel="stylesheet" href="css/variables-8adf115d.css">
<link rel="stylesheet" href="css/general-0392ca55.css">
<link rel="stylesheet" href="css/chrome-fc474251.css">
<link rel="stylesheet" href="css/print-9e4910d8.css" media="print">
<!-- Fonts -->
<link rel="stylesheet" href="fonts/fonts-9644e21d.css">
<!-- Highlight.js Stylesheets -->
<link rel="stylesheet" id="mdbook-highlight-css" href="highlight-493f70e1.css">
<link rel="stylesheet" id="mdbook-tomorrow-night-css" href="tomorrow-night-4c0ae647.css">
<link rel="stylesheet" id="mdbook-ayu-highlight-css" href="ayu-highlight-3fdfc3ac.css">
<!-- Custom theme stylesheets -->
<link rel="stylesheet" href="ferris-d33b75bf.css">
<link rel="stylesheet" href="theme/2018-edition-4e126c62.css">
<link rel="stylesheet" href="theme/semantic-notes-9b5766c0.css">
<link rel="stylesheet" href="theme/listing-cab26221.css">
<!-- Provide site root and default themes to javascript -->
<script>
const path_to_root = "";
const default_light_theme = "light";
const default_dark_theme = "navy";
window.path_to_searchindex_js = "searchindex-6a1da8cc.js";
</script>
<!-- Start loading toc.js asap -->
<script src="toc-0e4ce700.js"></script>
</head>
<body>
<div id="mdbook-help-container">
<div id="mdbook-help-popup">
<h2 class="mdbook-help-title">Keyboard shortcuts</h2>
<div>
<p>Press <kbd></kbd> or <kbd></kbd> to navigate between chapters</p>
<p>Press <kbd>S</kbd> or <kbd>/</kbd> to search in the book</p>
<p>Press <kbd>?</kbd> to show this help</p>
<p>Press <kbd>Esc</kbd> to hide this help</p>
</div>
</div>
</div>
<div id="mdbook-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="mdbook-sidebar-toggle-anchor" class="hidden">
<!-- Hide / unhide sidebar before it is displayed -->
<script>
let sidebar = null;
const sidebar_toggle = document.getElementById("mdbook-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 = false;
}
if (sidebar === 'visible') {
sidebar_toggle.checked = true;
} else {
html.classList.remove('sidebar-visible');
}
</script>
<nav id="mdbook-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="mdbook-sidebar-resize-handle" class="sidebar-resize-handle">
<div class="sidebar-resize-indicator"></div>
</div>
</nav>
<div id="mdbook-page-wrapper" class="page-wrapper">
<div class="page">
<div id="mdbook-menu-bar-hover-placeholder"></div>
<div id="mdbook-menu-bar" class="menu-bar sticky">
<div class="left-buttons">
<label id="mdbook-sidebar-toggle" class="icon-button" for="mdbook-sidebar-toggle-anchor" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="mdbook-sidebar">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M0 96C0 78.3 14.3 64 32 64H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32C14.3 128 0 113.7 0 96zM0 256c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32s-14.3 32-32 32H32c-17.7 0-32-14.3-32-32zM448 416c0 17.7-14.3 32-32 32H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H416c17.7 0 32 14.3 32 32z"/></svg></span>
</label>
<button id="mdbook-theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="mdbook-theme-list">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M371.3 367.1c27.3-3.9 51.9-19.4 67.2-42.9L600.2 74.1c12.6-19.5 9.4-45.3-7.6-61.2S549.7-4.4 531.1 9.6L294.4 187.2c-24 18-38.2 46.1-38.4 76.1L371.3 367.1zm-19.6 25.4l-116-104.4C175.9 290.3 128 339.6 128 400c0 3.9 .2 7.8 .6 11.6c1.8 17.5-10.2 36.4-27.8 36.4H96c-17.7 0-32 14.3-32 32s14.3 32 32 32H240c61.9 0 112-50.1 112-112c0-2.5-.1-5-.2-7.5z"/></svg></span>
</button>
<ul id="mdbook-theme-list" class="theme-popup" aria-label="Themes" role="menu">
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-default_theme">Auto</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-light">Light</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-rust">Rust</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-coal">Coal</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-navy">Navy</button></li>
<li role="none"><button role="menuitem" class="theme" id="mdbook-theme-ayu">Ayu</button></li>
</ul>
<button id="mdbook-search-toggle" class="icon-button" type="button" title="Search (`/`)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="/ s" aria-controls="mdbook-searchbar">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352c79.5 0 144-64.5 144-144s-64.5-144-144-144S64 128.5 64 208s64.5 144 144 144z"/></svg></span>
</button>
</div>
<h1 class="menu-title">The Rust Programming Language</h1>
<div class="right-buttons">
<a href="print.html" title="Print this book" aria-label="Print this book">
<span class=fa-svg id="print-button"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M128 0C92.7 0 64 28.7 64 64v96h64V64H354.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zM384 352v32 64H128V384 368 352H384zm64 32h32c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32H64v64c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V384zm-16-88c-13.3 0-24-10.7-24-24s10.7-24 24-24s24 10.7 24 24s-10.7 24-24 24z"/></svg></span>
</a>
<a href="https://github.com/rust-lang/book" title="Git repository" aria-label="Git repository">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg></span>
</a>
</div>
</div>
<div id="mdbook-search-wrapper" class="hidden">
<form id="mdbook-searchbar-outer" class="searchbar-outer">
<div class="search-wrapper">
<input type="search" id="mdbook-searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="mdbook-searchresults-outer" aria-describedby="searchresults-header">
<div class="spinner-wrapper">
<span class=fa-svg id="fa-spin"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M304 48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zm0 416c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM48 304c26.5 0 48-21.5 48-48s-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48zm464-48c0-26.5-21.5-48-48-48s-48 21.5-48 48s21.5 48 48 48s48-21.5 48-48zM142.9 437c18.7-18.7 18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zm0-294.2c18.7-18.7 18.7-49.1 0-67.9S93.7 56.2 75 75s-18.7 49.1 0 67.9s49.1 18.7 67.9 0zM369.1 437c18.7 18.7 49.1 18.7 67.9 0s18.7-49.1 0-67.9s-49.1-18.7-67.9 0s-18.7 49.1 0 67.9z"/></svg></span>
</div>
</div>
</form>
<div id="mdbook-searchresults-outer" class="searchresults-outer hidden">
<div id="mdbook-searchresults-header" class="searchresults-header"></div>
<ul id="mdbook-searchresults">
</ul>
</div>
</div>
<!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
<script>
document.getElementById('mdbook-sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
document.getElementById('mdbook-sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
Array.from(document.querySelectorAll('#mdbook-sidebar a')).forEach(function(link) {
link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
});
</script>
<div id="mdbook-content" class="content">
<main>
<h2 id="defining-an-enum"><a class="header" href="#defining-an-enum">Defining an Enum</a></h2>
<p>Where structs give you a way of grouping together related fields and data, like
a <code>Rectangle</code> with its <code>width</code> and <code>height</code>, enums give you a way of saying a
value is one of a possible set of values. For example, we may want to say that
<code>Rectangle</code> is one of a set of possible shapes that also includes <code>Circle</code> and
<code>Triangle</code>. To do this, Rust allows us to encode these possibilities as an enum.</p>
<p>Lets look at a situation we might want to express in code and see why enums
are useful and more appropriate than structs in this case. Say we need to work
with IP addresses. Currently, two major standards are used for IP addresses:
version four and version six. Because these are the only possibilities for an
IP address that our program will come across, we can <em>enumerate</em> all possible
variants, which is where enumeration gets its name.</p>
<p>Any IP address can be either a version four or a version six address, but not
both at the same time. That property of IP addresses makes the enum data
structure appropriate because an enum value can only be one of its variants.
Both version four and version six addresses are still fundamentally IP
addresses, so they should be treated as the same type when the code is handling
situations that apply to any kind of IP address.</p>
<p>We can express this concept in code by defining an <code>IpAddrKind</code> enumeration and
listing the possible kinds an IP address can be, <code>V4</code> and <code>V6</code>. These are the
variants of the enum:</p>
<pre class="playground"><code class="language-rust edition2024">enum IpAddrKind {
V4,
V6,
}
<span class="boring">
</span><span class="boring">fn main() {
</span><span class="boring"> let four = IpAddrKind::V4;
</span><span class="boring"> let six = IpAddrKind::V6;
</span><span class="boring">
</span><span class="boring"> route(IpAddrKind::V4);
</span><span class="boring"> route(IpAddrKind::V6);
</span><span class="boring">}
</span><span class="boring">
</span><span class="boring">fn route(ip_kind: IpAddrKind) {}</span></code></pre>
<p><code>IpAddrKind</code> is now a custom data type that we can use elsewhere in our code.</p>
<h3 id="enum-values"><a class="header" href="#enum-values">Enum Values</a></h3>
<p>We can create instances of each of the two variants of <code>IpAddrKind</code> like this:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">enum IpAddrKind {
</span><span class="boring"> V4,
</span><span class="boring"> V6,
</span><span class="boring">}
</span><span class="boring">
</span><span class="boring">fn main() {
</span> let four = IpAddrKind::V4;
let six = IpAddrKind::V6;
<span class="boring">
</span><span class="boring"> route(IpAddrKind::V4);
</span><span class="boring"> route(IpAddrKind::V6);
</span><span class="boring">}
</span><span class="boring">
</span><span class="boring">fn route(ip_kind: IpAddrKind) {}</span></code></pre>
<p>Note that the variants of the enum are namespaced under its identifier, and we
use a double colon to separate the two. This is useful because now both values
<code>IpAddrKind::V4</code> and <code>IpAddrKind::V6</code> are of the same type: <code>IpAddrKind</code>. We
can then, for instance, define a function that takes any <code>IpAddrKind</code>:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">enum IpAddrKind {
</span><span class="boring"> V4,
</span><span class="boring"> V6,
</span><span class="boring">}
</span><span class="boring">
</span><span class="boring">fn main() {
</span><span class="boring"> let four = IpAddrKind::V4;
</span><span class="boring"> let six = IpAddrKind::V6;
</span><span class="boring">
</span><span class="boring"> route(IpAddrKind::V4);
</span><span class="boring"> route(IpAddrKind::V6);
</span><span class="boring">}
</span><span class="boring">
</span>fn route(ip_kind: IpAddrKind) {}</code></pre>
<p>And we can call this function with either variant:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">enum IpAddrKind {
</span><span class="boring"> V4,
</span><span class="boring"> V6,
</span><span class="boring">}
</span><span class="boring">
</span><span class="boring">fn main() {
</span><span class="boring"> let four = IpAddrKind::V4;
</span><span class="boring"> let six = IpAddrKind::V6;
</span><span class="boring">
</span> route(IpAddrKind::V4);
route(IpAddrKind::V6);
<span class="boring">}
</span><span class="boring">
</span><span class="boring">fn route(ip_kind: IpAddrKind) {}</span></code></pre>
<p>Using enums has even more advantages. Thinking more about our IP address type,
at the moment we dont have a way to store the actual IP address <em>data</em>; we
only know what <em>kind</em> it is. Given that you just learned about structs in
Chapter 5, you might be tempted to tackle this problem with structs as shown in
Listing 6-1.</p>
<figure class="listing" id="listing-6-1">
<pre class="playground"><code class="language-rust edition2024"><span class="boring">fn main() {
</span> enum IpAddrKind {
V4,
V6,
}
struct IpAddr {
kind: IpAddrKind,
address: String,
}
let home = IpAddr {
kind: IpAddrKind::V4,
address: String::from("127.0.0.1"),
};
let loopback = IpAddr {
kind: IpAddrKind::V6,
address: String::from("::1"),
};
<span class="boring">}</span></code></pre>
<figcaption><a href="#listing-6-1">Listing 6-1</a>: Storing the data and <code>IpAddrKind</code> variant of an IP address using a <code>struct</code></figcaption>
</figure>
<p>Here, weve defined a struct <code>IpAddr</code> that has two fields: a <code>kind</code> field that
is of type <code>IpAddrKind</code> (the enum we defined previously) and an <code>address</code> field
of type <code>String</code>. We have two instances of this struct. The first is <code>home</code>,
and it has the value <code>IpAddrKind::V4</code> as its <code>kind</code> with associated address
data of <code>127.0.0.1</code>. The second instance is <code>loopback</code>. It has the other
variant of <code>IpAddrKind</code> as its <code>kind</code> value, <code>V6</code>, and has address <code>::1</code>
associated with it. Weve used a struct to bundle the <code>kind</code> and <code>address</code>
values together, so now the variant is associated with the value.</p>
<p>However, representing the same concept using just an enum is more concise:
Rather than an enum inside a struct, we can put data directly into each enum
variant. This new definition of the <code>IpAddr</code> enum says that both <code>V4</code> and <code>V6</code>
variants will have associated <code>String</code> values:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">fn main() {
</span> enum IpAddr {
V4(String),
V6(String),
}
let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));
<span class="boring">}</span></code></pre>
<p>We attach data to each variant of the enum directly, so there is no need for an
extra struct. Here, its also easier to see another detail of how enums work:
The name of each enum variant that we define also becomes a function that
constructs an instance of the enum. That is, <code>IpAddr::V4()</code> is a function call
that takes a <code>String</code> argument and returns an instance of the <code>IpAddr</code> type. We
automatically get this constructor function defined as a result of defining the
enum.</p>
<p>Theres another advantage to using an enum rather than a struct: Each variant
can have different types and amounts of associated data. Version four IP
addresses will always have four numeric components that will have values
between 0 and 255. If we wanted to store <code>V4</code> addresses as four <code>u8</code> values but
still express <code>V6</code> addresses as one <code>String</code> value, we wouldnt be able to with
a struct. Enums handle this case with ease:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">fn main() {
</span> enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
<span class="boring">}</span></code></pre>
<p>Weve shown several different ways to define data structures to store version
four and version six IP addresses. However, as it turns out, wanting to store
IP addresses and encode which kind they are is so common that <a href="../std/net/enum.IpAddr.html">the standard
library has a definition we can use!</a><!-- ignore --> Lets look at how
the standard library defines <code>IpAddr</code>. It has the exact enum and variants that
weve defined and used, but it embeds the address data inside the variants in
the form of two different structs, which are defined differently for each
variant:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>struct Ipv4Addr {
// --snip--
}
struct Ipv6Addr {
// --snip--
}
enum IpAddr {
V4(Ipv4Addr),
V6(Ipv6Addr),
}
<span class="boring">}</span></code></pre>
<p>This code illustrates that you can put any kind of data inside an enum variant:
strings, numeric types, or structs, for example. You can even include another
enum! Also, standard library types are often not much more complicated than
what you might come up with.</p>
<p>Note that even though the standard library contains a definition for <code>IpAddr</code>,
we can still create and use our own definition without conflict because we
havent brought the standard librarys definition into our scope. Well talk
more about bringing types into scope in Chapter 7.</p>
<p>Lets look at another example of an enum in Listing 6-2: This one has a wide
variety of types embedded in its variants.</p>
<figure class="listing" id="listing-6-2">
<pre class="playground"><code class="language-rust edition2024">enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
<span class="boring">
</span><span class="boring">fn main() {}</span></code></pre>
<figcaption><a href="#listing-6-2">Listing 6-2</a>: A <code>Message</code> enum whose variants each store different amounts and types of values</figcaption>
</figure>
<p>This enum has four variants with different types:</p>
<ul>
<li><code>Quit</code>: Has no data associated with it at all</li>
<li><code>Move</code>: Has named fields, like a struct does</li>
<li><code>Write</code>: Includes a single <code>String</code></li>
<li><code>ChangeColor</code>: Includes three <code>i32</code> values</li>
</ul>
<p>Defining an enum with variants such as the ones in Listing 6-2 is similar to
defining different kinds of struct definitions, except the enum doesnt use the
<code>struct</code> keyword and all the variants are grouped together under the <code>Message</code>
type. The following structs could hold the same data that the preceding enum
variants hold:</p>
<pre class="playground"><code class="language-rust edition2024">struct QuitMessage; // unit struct
struct MoveMessage {
x: i32,
y: i32,
}
struct WriteMessage(String); // tuple struct
struct ChangeColorMessage(i32, i32, i32); // tuple struct
<span class="boring">
</span><span class="boring">fn main() {}</span></code></pre>
<p>But if we used the different structs, each of which has its own type, we
couldnt as easily define a function to take any of these kinds of messages as
we could with the <code>Message</code> enum defined in Listing 6-2, which is a single type.</p>
<p>There is one more similarity between enums and structs: Just as were able to
define methods on structs using <code>impl</code>, were also able to define methods on
enums. Heres a method named <code>call</code> that we could define on our <code>Message</code> enum:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">fn main() {
</span><span class="boring"> enum Message {
</span><span class="boring"> Quit,
</span><span class="boring"> Move { x: i32, y: i32 },
</span><span class="boring"> Write(String),
</span><span class="boring"> ChangeColor(i32, i32, i32),
</span><span class="boring"> }
</span><span class="boring">
</span> impl Message {
fn call(&amp;self) {
// method body would be defined here
}
}
let m = Message::Write(String::from("hello"));
m.call();
<span class="boring">}</span></code></pre>
<p>The body of the method would use <code>self</code> to get the value that we called the
method on. In this example, weve created a variable <code>m</code> that has the value
<code>Message::Write(String::from("hello"))</code>, and that is what <code>self</code> will be in the
body of the <code>call</code> method when <code>m.call()</code> runs.</p>
<p>Lets look at another enum in the standard library that is very common and
useful: <code>Option</code>.</p>
<!-- Old headings. Do not remove or links may break. -->
<p><a id="the-option-enum-and-its-advantages-over-null-values"></a></p>
<h3 id="the-option-enum"><a class="header" href="#the-option-enum">The <code>Option</code> Enum</a></h3>
<p>This section explores a case study of <code>Option</code>, which is another enum defined
by the standard library. The <code>Option</code> type encodes the very common scenario in
which a value could be something, or it could be nothing.</p>
<p>For example, if you request the first item in a non-empty list, you would get
a value. If you request the first item in an empty list, you would get nothing.
Expressing this concept in terms of the type system means the compiler can
check whether youve handled all the cases you should be handling; this
functionality can prevent bugs that are extremely common in other programming
languages.</p>
<p>Programming language design is often thought of in terms of which features you
include, but the features you exclude are important too. Rust doesnt have the
null feature that many other languages have. <em>Null</em> is a value that means there
is no value there. In languages with null, variables can always be in one of
two states: null or not-null.</p>
<p>In his 2009 presentation “Null References: The Billion Dollar Mistake,” Tony
Hoare, the inventor of null, had this to say:</p>
<blockquote>
<p>I call it my billion-dollar mistake. At that time, I was designing the first
comprehensive type system for references in an object-oriented language. My
goal was to ensure that all use of references should be absolutely safe, with
checking performed automatically by the compiler. But I couldnt resist the
temptation to put in a null reference, simply because it was so easy to
implement. This has led to innumerable errors, vulnerabilities, and system
crashes, which have probably caused a billion dollars of pain and damage in
the last forty years.</p>
</blockquote>
<p>The problem with null values is that if you try to use a null value as a
not-null value, youll get an error of some kind. Because this null or not-null
property is pervasive, its extremely easy to make this kind of error.</p>
<p>However, the concept that null is trying to express is still a useful one: A
null is a value that is currently invalid or absent for some reason.</p>
<p>The problem isnt really with the concept but with the particular
implementation. As such, Rust does not have nulls, but it does have an enum
that can encode the concept of a value being present or absent. This enum is
<code>Option&lt;T&gt;</code>, and it is <a href="../std/option/enum.Option.html">defined by the standard library</a><!-- ignore -->
as follows:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>enum Option&lt;T&gt; {
None,
Some(T),
}
<span class="boring">}</span></code></pre>
<p>The <code>Option&lt;T&gt;</code> enum is so useful that its even included in the prelude; you
dont need to bring it into scope explicitly. Its variants are also included in
the prelude: You can use <code>Some</code> and <code>None</code> directly without the <code>Option::</code>
prefix. The <code>Option&lt;T&gt;</code> enum is still just a regular enum, and <code>Some(T)</code> and
<code>None</code> are still variants of type <code>Option&lt;T&gt;</code>.</p>
<p>The <code>&lt;T&gt;</code> syntax is a feature of Rust we havent talked about yet. Its a
generic type parameter, and well cover generics in more detail in Chapter 10.
For now, all you need to know is that <code>&lt;T&gt;</code> means that the <code>Some</code> variant of
the <code>Option</code> enum can hold one piece of data of any type, and that each
concrete type that gets used in place of <code>T</code> makes the overall <code>Option&lt;T&gt;</code> type
a different type. Here are some examples of using <code>Option</code> values to hold
number types and char types:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">fn main() {
</span> let some_number = Some(5);
let some_char = Some('e');
let absent_number: Option&lt;i32&gt; = None;
<span class="boring">}</span></code></pre>
<p>The type of <code>some_number</code> is <code>Option&lt;i32&gt;</code>. The type of <code>some_char</code> is
<code>Option&lt;char&gt;</code>, which is a different type. Rust can infer these types because
weve specified a value inside the <code>Some</code> variant. For <code>absent_number</code>, Rust
requires us to annotate the overall <code>Option</code> type: The compiler cant infer the
type that the corresponding <code>Some</code> variant will hold by looking only at a
<code>None</code> value. Here, we tell Rust that we mean for <code>absent_number</code> to be of type
<code>Option&lt;i32&gt;</code>.</p>
<p>When we have a <code>Some</code> value, we know that a value is present, and the value is
held within the <code>Some</code>. When we have a <code>None</code> value, in some sense it means the
same thing as null: We dont have a valid value. So, why is having <code>Option&lt;T&gt;</code>
any better than having null?</p>
<p>In short, because <code>Option&lt;T&gt;</code> and <code>T</code> (where <code>T</code> can be any type) are different
types, the compiler wont let us use an <code>Option&lt;T&gt;</code> value as if it were
definitely a valid value. For example, this code wont compile, because its
trying to add an <code>i8</code> to an <code>Option&lt;i8&gt;</code>:</p>
<pre><code class="language-rust ignore does_not_compile"><span class="boring">fn main() {
</span> let x: i8 = 5;
let y: Option&lt;i8&gt; = Some(5);
let sum = x + y;
<span class="boring">}</span></code></pre>
<p>If we run this code, we get an error message like this one:</p>
<pre><code class="language-console">$ cargo run
Compiling enums v0.1.0 (file:///projects/enums)
error[E0277]: cannot add `Option&lt;i8&gt;` to `i8`
--&gt; src/main.rs:5:17
|
5 | let sum = x + y;
| ^ no implementation for `i8 + Option&lt;i8&gt;`
|
= help: the trait `Add&lt;Option&lt;i8&gt;&gt;` is not implemented for `i8`
= help: the following other types implement trait `Add&lt;Rhs&gt;`:
`&amp;i8` implements `Add&lt;i8&gt;`
`&amp;i8` implements `Add`
`i8` implements `Add&lt;&amp;i8&gt;`
`i8` implements `Add`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `enums` (bin "enums") due to 1 previous error
</code></pre>
<p>Intense! In effect, this error message means that Rust doesnt understand how
to add an <code>i8</code> and an <code>Option&lt;i8&gt;</code>, because theyre different types. When we
have a value of a type like <code>i8</code> in Rust, the compiler will ensure that we
always have a valid value. We can proceed confidently without having to check
for null before using that value. Only when we have an <code>Option&lt;i8&gt;</code> (or
whatever type of value were working with) do we have to worry about possibly
not having a value, and the compiler will make sure we handle that case before
using the value.</p>
<p>In other words, you have to convert an <code>Option&lt;T&gt;</code> to a <code>T</code> before you can
perform <code>T</code> operations with it. Generally, this helps catch one of the most
common issues with null: assuming that something isnt null when it actually is.</p>
<p>Eliminating the risk of incorrectly assuming a not-null value helps you be more
confident in your code. In order to have a value that can possibly be null, you
must explicitly opt in by making the type of that value <code>Option&lt;T&gt;</code>. Then, when
you use that value, you are required to explicitly handle the case when the
value is null. Everywhere that a value has a type that isnt an <code>Option&lt;T&gt;</code>,
you <em>can</em> safely assume that the value isnt null. This was a deliberate design
decision for Rust to limit nulls pervasiveness and increase the safety of Rust
code.</p>
<p>So how do you get the <code>T</code> value out of a <code>Some</code> variant when you have a value
of type <code>Option&lt;T&gt;</code> so that you can use that value? The <code>Option&lt;T&gt;</code> enum has a
large number of methods that are useful in a variety of situations; you can
check them out in <a href="../std/option/enum.Option.html">its documentation</a><!-- ignore -->. Becoming familiar
with the methods on <code>Option&lt;T&gt;</code> will be extremely useful in your journey with
Rust.</p>
<p>In general, in order to use an <code>Option&lt;T&gt;</code> value, you want to have code that
will handle each variant. You want some code that will run only when you have a
<code>Some(T)</code> value, and this code is allowed to use the inner <code>T</code>. You want some
other code to run only if you have a <code>None</code> value, and that code doesnt have a
<code>T</code> value available. The <code>match</code> expression is a control flow construct that
does just this when used with enums: It will run different code depending on
which variant of the enum it has, and that code can use the data inside the
matching value.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch06-00-enums.html" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg></span>
</a>
<a rel="next prefetch" href="ch06-02-match.html" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z"/></svg></span>
</a>
<div style="clear: both"></div>
</nav>
</div>
</div>
<nav class="nav-wide-wrapper" aria-label="Page navigation">
<a rel="prev" href="ch06-00-enums.html" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 246.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z"/></svg></span>
</a>
<a rel="next prefetch" href="ch06-02-match.html" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
<span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z"/></svg></span>
</a>
</nav>
</div>
<template id=fa-eye><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></template>
<template id=fa-eye-slash><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2S-1.2 34.7 9.2 42.9l592 464c10.4 8.2 25.5 6.3 33.7-4.1s6.3-25.5-4.1-33.7L525.6 386.7c39.6-40.6 66.4-86.1 79.9-118.4c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-68.2 0-125 26.3-169.3 60.8L38.8 5.1zM223.1 149.5C248.6 126.2 282.7 112 320 112c79.5 0 144 64.5 144 144c0 24.9-6.3 48.3-17.4 68.7L408 294.5c5.2-11.8 8-24.8 8-38.5c0-53-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6c0 10.2-2.4 19.8-6.6 28.3l-90.3-70.8zm223.1 298L373 389.9c-16.4 6.5-34.3 10.1-53 10.1c-79.5 0-144-64.5-144-144c0-6.9 .5-13.6 1.4-20.2L83.1 161.5C60.3 191.2 44 220.8 34.5 243.7c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c47.8 0 89.9-12.9 126.2-32.5z"/></svg></span></template>
<template id=fa-copy><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M502.6 70.63l-61.25-61.25C435.4 3.371 427.2 0 418.7 0H255.1c-35.35 0-64 28.66-64 64l.0195 256C192 355.4 220.7 384 256 384h192c35.2 0 64-28.8 64-64V93.25C512 84.77 508.6 76.63 502.6 70.63zM464 320c0 8.836-7.164 16-16 16H255.1c-8.838 0-16-7.164-16-16L239.1 64.13c0-8.836 7.164-16 16-16h128L384 96c0 17.67 14.33 32 32 32h47.1V320zM272 448c0 8.836-7.164 16-16 16H63.1c-8.838 0-16-7.164-16-16L47.98 192.1c0-8.836 7.164-16 16-16H160V128H63.99c-35.35 0-64 28.65-64 64l.0098 256C.002 483.3 28.66 512 64 512h192c35.2 0 64-28.8 64-64v-32h-47.1L272 448z"/></svg></span></template>
<template id=fa-play><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M73 39c-14.8-9.1-33.4-9.4-48.5-.9S0 62.6 0 80V432c0 17.4 9.4 33.4 24.5 41.9s33.7 8.1 48.5-.9L361 297c14.3-8.7 23-24.2 23-41s-8.7-32.2-23-41L73 39z"/></svg></span></template>
<template id=fa-clock-rotate-left><span class=fa-svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2022 Fonticons, Inc. --><path d="M75 75L41 41C25.9 25.9 0 36.6 0 57.9V168c0 13.3 10.7 24 24 24H134.1c21.4 0 32.1-25.9 17-41l-30.8-30.8C155 85.5 203 64 256 64c106 0 192 86 192 192s-86 192-192 192c-40.8 0-78.6-12.7-109.7-34.4c-14.5-10.1-34.4-6.6-44.6 7.9s-6.6 34.4 7.9 44.6C151.2 495 201.7 512 256 512c141.4 0 256-114.6 256-256S397.4 0 256 0C185.3 0 121.3 28.7 75 75zm181 53c-13.3 0-24 10.7-24 24V256c0 6.4 2.5 12.5 7 17l72 72c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9l-65-65V152c0-13.3-10.7-24-24-24z"/></svg></span></template>
<script>
window.playground_copyable = true;
</script>
<script src="elasticlunr-ef4e11c1.min.js"></script>
<script src="mark-09e88c2c.min.js"></script>
<script src="searcher-09f2665d.js"></script>
<script src="clipboard-1626706a.min.js"></script>
<script src="highlight-abc7f01d.js"></script>
<script src="book-c22b7243.js"></script>
<!-- Custom JS scripts -->
<script src="ferris-2317480c.js"></script>
</div>
</body>
</html>