You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
trpl-zh-cn/ch03-02-data-types.html

470 lines
43 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!DOCTYPE HTML>
<html lang="en" class="light sidebar-visible" dir="ltr">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>数据类型 - Rust 程序设计语言 简体中文版</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-2459343d.css">
<link rel="stylesheet" href="css/chrome-ae938929.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-e0ffcbc3.js";
</script>
<!-- Start loading toc.js asap -->
<script src="toc-fb31ca2f.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">Rust 程序设计语言 简体中文版</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/KaiserY/trpl-zh-cn/tree/main" 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="数据类型"><a class="header" href="#数据类型">数据类型</a></h2>
<p><a href="https://github.com/rust-lang/book/blob/9cc190796f28505c7a9a9cacea42f50d895ff3bd/src/ch03-02-data-types.md">ch03-02-data-types.md</a></p>
<p>在 Rust 中,每个值都属于某种特定的 <strong>数据类型</strong><em>data type</em>),这会告诉 Rust 当前指定的是什么种类的数据从而知道该如何处理这些数据。我们将看到两类数据类型的子集标量scalar和复合compound</p>
<p>记住Rust 是 <strong>静态类型</strong><em>statically typed</em>)语言,也就是说,它必须在编译时就知道所有变量的类型。编译器通常可以根据值以及它的使用方式推断出我们想要使用的类型。但在存在多种可能类型的情况下,比如我们在第二章<a href="ch02-00-guessing-game-tutorial.html#比较猜测的数字和秘密数字">“比较猜测的数字和秘密数字”</a>一节中使用 <code>parse</code><code>String</code> 转换为数值类型时,就必须加上类型注解,像这样:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let guess: u32 = "42".parse().expect("Not a number!");
<span class="boring">}</span></code></pre>
<p>如果不按前面的代码那样加上 <code>: u32</code> 类型注解Rust 就会显示如下错误。这说明编译器需要我们提供更多信息,才能知道我们想使用哪一种类型:</p>
<pre><code class="language-console">$ cargo build
Compiling no_type_annotations v0.1.0 (file:///projects/no_type_annotations)
error[E0284]: type annotations needed
--&gt; src/main.rs:2:9
|
2 | let guess = "42".parse().expect("Not a number!");
| ^^^^^ ----- type must be known at this point
|
= note: cannot satisfy `&lt;_ as FromStr&gt;::Err == _`
help: consider giving `guess` an explicit type
|
2 | let guess: /* Type */ = "42".parse().expect("Not a number!");
| ++++++++++++
For more information about this error, try `rustc --explain E0284`.
error: could not compile `no_type_annotations` (bin "no_type_annotations") due to 1 previous error
</code></pre>
<p>你会看到其它数据类型的各种类型注解。</p>
<h3 id="标量类型"><a class="header" href="#标量类型">标量类型</a></h3>
<p><strong>标量</strong><em>scalar</em>类型代表一个单独的值。Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。你可能在其他语言中见过它们。让我们深入了解它们在 Rust 中是如何工作的。</p>
<h4 id="整型"><a class="header" href="#整型">整型</a></h4>
<p><strong>整型</strong> 是没有小数部分的数字。我们在第二章已经用过 <code>u32</code> 这种整数类型。这个类型声明表明,它关联的值应该是一个占用 32 位空间的无符号整数(有符号整数类型以 <code>i</code> 开头,而不是 <code>u</code>)。表格 3-1 展示了 Rust 内建的整数类型。我们可以使用其中任意一种来声明整数值的类型。</p>
<p><span class="caption">表格 3-1: Rust 中的整型</span></p>
<div class="table-wrapper">
<table>
<thead>
<tr><th>长度</th><th>有符号</th><th>无符号</th></tr>
</thead>
<tbody>
<tr><td>8-bit</td><td><code>i8</code></td><td><code>u8</code></td></tr>
<tr><td>16-bit</td><td><code>i16</code></td><td><code>u16</code></td></tr>
<tr><td>32-bit</td><td><code>i32</code></td><td><code>u32</code></td></tr>
<tr><td>64-bit</td><td><code>i64</code></td><td><code>u64</code></td></tr>
<tr><td>128-bit</td><td><code>i128</code></td><td><code>u128</code></td></tr>
<tr><td>架构相关</td><td><code>isize</code></td><td><code>usize</code></td></tr>
</tbody>
</table>
</div>
<p>每一种变体都可以是有符号或无符号的,并且具有明确的大小。<strong>有符号</strong><strong>无符号</strong> 指的是数字是否可能为负数。换句话说,这个数字是需要带符号的(有符号),还是它永远为正,因此无需符号(无符号)。这有点像我们在纸上写数字:当符号有意义时,数字前面会带上加号或减号;但如果可以安全地假定它是正数,通常就不会写加号。有符号数使用<a href="https://en.wikipedia.org/wiki/Two%27s_complement">二进制补码twos complement</a>表示。</p>
<p>每一个有符号的变体可以储存包含从 -(2<sup>n - 1</sup>) 到 2<sup>n - 1</sup> - 1 在内的数字,这里 <em>n</em> 是变体使用的位数。所以 <code>i8</code> 可以储存从 -(2<sup>7</sup>) 到 2<sup>7</sup> - 1 在内的数字,也就是从 -128 到 127。无符号的变体可以储存从 0 到 2<sup>n</sup> - 1 的数字,所以 <code>u8</code> 可以储存从 0 到 2<sup>8</sup> - 1 的数字,也就是从 0 到 255。</p>
<p>另外,<code>isize</code><code>usize</code> 类型依赖运行程序的计算机架构64 位架构上它们是 64 位的32 位架构上它们是 32 位的。</p>
<p>你可以使用表格 3-2 中展示的任意一种形式来编写整数字面值。请注意,那些可能对应多种数值类型的数字字面值可以带上类型后缀,例如 <code>57u8</code>,用来显式指定类型。数字字面值也可以使用 <code>_</code> 作为视觉分隔符,方便阅读,例如 <code>1_000</code>,它和 <code>1000</code> 的值完全相同。</p>
<p><span class="caption">表格 3-2: Rust 中的整型字面值</span></p>
<div class="table-wrapper">
<table>
<thead>
<tr><th>数字字面值</th><th>例子</th></tr>
</thead>
<tbody>
<tr><td>Decimal十进制</td><td><code>98_222</code></td></tr>
<tr><td>Hex十六进制</td><td><code>0xff</code></td></tr>
<tr><td>Octal八进制</td><td><code>0o77</code></td></tr>
<tr><td>Binary二进制</td><td><code>0b1111_0000</code></td></tr>
<tr><td>Byte字节字面值仅限 <code>u8</code></td><td><code>b'A'</code></td></tr>
</tbody>
</table>
</div>
<p>那么该使用哪种整型呢如果拿不定主意Rust 的默认类型通常是一个不错的起点:整型默认是 <code>i32</code>。而 <code>isize</code><code>usize</code> 主要用在对某种集合进行索引的场景中。</p>
<blockquote>
<h5 id="整型溢出"><a class="header" href="#整型溢出">整型溢出</a></h5>
<p>假设你有一个 <code>u8</code> 类型的变量,它可以保存 <code>0</code><code>255</code> 之间的值。如果你试图把它改成超出该范围的值,比如 <code>256</code>,就会发生 <strong>整型溢出</strong><em>integer overflow</em>),并可能导致两种行为之一。当你在 debug 模式下编译时Rust 会加入整型溢出的检查,并在发生这种情况时让程序在运行时 <em>panic</em>。Rust 用 <em>panicking</em> 这个术语表示程序因错误而退出;我们会在第九章<a href="ch09-01-unrecoverable-errors-with-panic.html"><code>panic!</code> 与不可恢复的错误”</a>一节中更深入地讨论 panic。</p>
<p>当你使用 <code>--release</code> flag 在 release 模式下编译时Rust <strong>不会</strong>加入会导致 panic 的整型溢出检查。相反如果发生溢出Rust 会执行一种叫做 <em>twos complement wrapping</em> 的行为。简而言之,超过该类型最大值的数会“回绕”到该类型所能表示的最小值。对于 <code>u8</code> 来说,<code>256</code> 会变成 <code>0</code><code>257</code> 会变成 <code>1</code>,依此类推。程序不会 panic但变量得到的值很可能不是你原本期望的值。依赖整型溢出的回绕行为通常被认为是一种错误。</p>
<p>为了显式地处理溢出的可能性,可以使用这几类标准库提供的原始数字类型方法:</p>
<ul>
<li>所有模式下都可以使用 <code>wrapping_*</code> 方法进行 wrapping<code>wrapping_add</code></li>
<li>如果 <code>checked_*</code> 方法发生溢出,则返回 <code>None</code></li>
<li><code>overflowing_*</code> 方法返回值和一个布尔值,表示是否出现溢出</li>
<li><code>saturating_*</code> 方法在值的最小值或最大值处进行饱和处理</li>
</ul>
</blockquote>
<h4 id="浮点型"><a class="header" href="#浮点型">浮点型</a></h4>
<p>Rust 也有两个原生的 <strong>浮点数</strong><em>floating-point numbers</em>类型它们是带小数点的数字。Rust 的浮点数类型是 <code>f32</code><code>f64</code>,分别占 32 位和 64 位。默认类型是 <code>f64</code>,因为在现代 CPU 中,它与 <code>f32</code> 速度几乎一样,不过精度更高。所有的浮点型都是有符号的。</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre class="playground"><code class="language-rust edition2024">fn main() {
let x = 2.0; // f64
let y: f32 = 3.0; // f32
}</code></pre>
<p>浮点数按照 IEEE-754 标准表示。</p>
<h4 id="数值运算"><a class="header" href="#数值运算">数值运算</a></h4>
<p>Rust 中的所有数字类型都支持基本数学运算:加法、减法、乘法、除法和取余。整数除法会向零舍入到最接近的整数。下面的代码展示了如何在 <code>let</code> 语句中使用各种数值运算:</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre class="playground"><code class="language-rust edition2024">fn main() {
// addition
let sum = 5 + 10;
// subtraction
let difference = 95.5 - 4.3;
// multiplication
let product = 4 * 30;
// division
let quotient = 56.7 / 32.2;
let truncated = -5 / 3; // 结果为 -1
// remainder
let remainder = 43 % 5;
}</code></pre>
<p>这些语句中的每个表达式使用了一个数学运算符并计算出了一个值,然后绑定给一个变量。<a href="appendix-02-operators.html">附录 B</a><!-- ignore --> 包含 Rust 提供的所有运算符的列表。</p>
<h4 id="布尔类型"><a class="header" href="#布尔类型">布尔类型</a></h4>
<p>正如其他大部分编程语言一样Rust 中的布尔类型有两个可能的值:<code>true</code><code>false</code>。Rust 中的布尔类型使用 <code>bool</code> 表示。例如:</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre class="playground"><code class="language-rust edition2024">fn main() {
let t = true;
let f: bool = false; // with explicit type annotation
}</code></pre>
<p>布尔值最主要的使用场景是条件表达式,例如 <code>if</code> 表达式。我们会在<a href="ch03-05-control-flow.html#控制流">“控制流”</a>一节介绍 <code>if</code> 表达式在 Rust 中是如何工作的。</p>
<h4 id="字符类型"><a class="header" href="#字符类型">字符类型</a></h4>
<p>Rust 的 <code>char</code> 类型是语言中最原始的字母类型。下面是一些声明 <code>char</code> 值的例子:</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre class="playground"><code class="language-rust edition2024">fn main() {
let c = 'z';
let z: char = ''; // with explicit type annotation
let heart_eyed_cat = '😻';
}</code></pre>
<p>注意,我们使用单引号来表示 <code>char</code> 字面值而字符串字面值使用的是双引号。Rust 的 <code>char</code> 类型大小为 4 个字节,并表示一个 Unicode 标量值Unicode Scalar Value这意味着它所能表示的内容远不止 ASCII。带重音符号的字母中文、日文、韩文字符emoji以及零宽空格都是 Rust 中合法的 <code>char</code> 值。Unicode 标量值的范围包括 <code>U+0000</code><code>U+D7FF</code>,以及 <code>U+E000</code><code>U+10FFFF</code>。不过,“字符”并不是 Unicode 中一个严格对应的概念,因此你直觉上认为的“字符”未必和 Rust 中的 <code>char</code> 一一对应。我们会在第八章<a href="ch08-02-strings.html#使用字符串储存-utf-8-编码的文本">“使用字符串储存 UTF-8 编码的文本”</a>中更详细地讨论这个主题。</p>
<h3 id="复合类型"><a class="header" href="#复合类型">复合类型</a></h3>
<p><strong>复合类型</strong><em>compound types</em>可以把多个值组合成一个类型。Rust 有两种原生的复合类型元组tuple和数组array</p>
<h4 id="元组类型"><a class="header" href="#元组类型">元组类型</a></h4>
<p>元组是一种将多个不同类型的值组合成一个复合类型的通用方式。元组长度固定:一旦声明,它的大小就不能增长或缩小。</p>
<p>我们通过在圆括号中写一组由逗号分隔的值来创建元组。元组中的每个位置都有一个类型,而且这些不同位置上的值类型不必相同。下面这个例子中加入了可选的类型注解:</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre class="playground"><code class="language-rust edition2024">fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
}</code></pre>
<p>变量 <code>tup</code> 绑定到整个元组上因为元组本身会被视为一个单独的复合值。为了从元组中取出单个值我们可以使用模式匹配pattern matching来解构destructure元组像这样</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre class="playground"><code class="language-rust edition2024">fn main() {
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {y}");
}</code></pre>
<p>程序首先创建了一个元组并绑定到 <code>tup</code> 变量上。接着使用了 <code>let</code> 和一个模式将 <code>tup</code> 分成了三个不同的变量,<code>x</code><code>y</code><code>z</code>。这叫做 <strong>解构</strong><em>destructuring</em>),因为它将一个元组拆成了三个部分。最后,程序打印出了 <code>y</code> 的值,也就是 <code>6.4</code></p>
<p>我们也可以使用点号(<code>.</code>)后跟值的索引来直接访问所需的元组元素。例如:</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre class="playground"><code class="language-rust edition2024">fn main() {
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
}</code></pre>
<p>这个程序创建了一个元组,<code>x</code>,然后使用其各自的索引访问元组中的每个元素。跟大多数编程语言一样,元组的第一个索引值是 0。</p>
<p>不带任何值的元组有一个特殊名字,叫做 <strong>单元unit</strong>。这种值以及其对应的类型都写作 <code>()</code>,表示空值或空的返回类型。如果一个表达式没有返回任何其他值,它就会隐式返回单元值。</p>
<h4 id="数组类型"><a class="header" href="#数组类型">数组类型</a></h4>
<p>另一种包含多个值的方式是 <strong>数组</strong><em>array</em>。和元组不同数组中的每个元素都必须具有相同类型。Rust 中的数组也不同于某些其他语言中的数组Rust 的数组长度是固定的。</p>
<p>我们将数组的值写成在方括号内,用逗号分隔的列表:</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre class="playground"><code class="language-rust edition2024">fn main() {
let a = [1, 2, 3, 4, 5];
}</code></pre>
<p>当你希望把数据分配在栈stack上而不是堆heap上时<a href="ch04-01-what-is-ownership.html#栈stack与堆heap">第四章</a>会更详细地讨论栈与堆),或者当你想确保始终拥有固定数量的元素时,数组就非常有用。不过,数组不如 vector 类型灵活。vector 是标准库提供的一种类似数组的集合类型,它 <strong>允许</strong> 长度增长或缩小。如果你不确定该用数组还是 vector那么很可能你应该用 vector。<a href="ch08-01-vectors.html">第八章</a>会更详细地讨论 vector。</p>
<p>不过,当你明确知道元素个数不会变化时,数组就更有用。例如,如果你在程序中使用月份名称,那么你大概会选择数组而不是 vector因为你知道它始终只有 12 个元素。</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let months = ["January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"];
<span class="boring">}</span></code></pre>
<p>可以像这样编写数组的类型:在方括号中包含每个元素的类型,后跟分号,再后跟数组元素的数量。</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let a: [i32; 5] = [1, 2, 3, 4, 5];
<span class="boring">}</span></code></pre>
<p>这里,<code>i32</code> 是每个元素的类型。分号之后,数字 <code>5</code> 表明该数组包含五个元素。</p>
<p>你还可以通过在方括号中指定初始值加分号再加元素个数的方式来创建一个每个元素都为相同值的数组:</p>
<pre class="playground"><code class="language-rust edition2024"><span class="boring">#![allow(unused)]
</span><span class="boring">fn main() {
</span>let a = [3; 5];
<span class="boring">}</span></code></pre>
<p>变量名为 <code>a</code> 的数组将包含 <code>5</code> 个元素,这些元素的值最初都将被设置为 <code>3</code>。这种写法与 <code>let a = [3, 3, 3, 3, 3];</code> 效果相同,但更简洁。</p>
<h5 id="访问数组元素"><a class="header" href="#访问数组元素">访问数组元素</a></h5>
<p>数组是在栈stack上分配的一整块、大小已知且固定的内存。你可以像下面这样使用索引来访问数组中的元素</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre class="playground"><code class="language-rust edition2024">fn main() {
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
}</code></pre>
<p>在这个例子中,叫做 <code>first</code> 的变量的值是 <code>1</code>,因为它是数组索引 <code>[0]</code> 的值。变量 <code>second</code> 将会是数组索引 <code>[1]</code> 的值 <code>2</code></p>
<h5 id="无效的数组元素访问"><a class="header" href="#无效的数组元素访问">无效的数组元素访问</a></h5>
<p>让我们看看如果尝试访问数组末尾之后的元素会发生什么。假设你运行下面这段代码,它类似于第 2 章中的猜数字游戏:从用户那里读取一个数组索引。</p>
<p><span class="filename">文件名src/main.rs</span></p>
<pre><code class="language-rust ignore panics">use std::io;
fn main() {
let a = [1, 2, 3, 4, 5];
println!("Please enter an array index.");
let mut index = String::new();
io::stdin()
.read_line(&amp;mut index)
.expect("Failed to read line");
let index: usize = index
.trim()
.parse()
.expect("Index entered was not a number");
let element = a[index];
println!("The value of the element at index {index} is: {element}");
}</code></pre>
<p>这段代码能够成功编译。如果你用 <code>cargo run</code> 运行它,并输入 <code>0</code><code>1</code><code>2</code><code>3</code><code>4</code>,程序就会打印出数组中对应索引位置的值。相反,如果你输入一个超出数组末尾的数字,比如 <code>10</code>,你就会看到像下面这样的输出:</p>
<pre><code class="language-console">thread 'main' panicked at src/main.rs:19:19:
index out of bounds: the len is 5 but the index is 10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
</code></pre>
<p>程序在索引操作中使用了无效值,因此产生了一个 <strong>运行时</strong> 错误。程序带着错误信息退出,并且没有执行最后那条 <code>println!</code> 语句。当你尝试通过索引访问元素时Rust 会检查你指定的索引是否小于数组长度。如果索引大于或等于数组长度Rust 就会 <em>panic</em>。这种检查必须在运行时完成,尤其是在这种场景下,因为编译器不可能知道用户之后运行代码时会输入什么值。</p>
<p>这是 Rust 内存安全原则在实践中的一个例子。在许多底层语言中不会进行这种检查因此如果你提供了错误的索引就可能访问到无效内存。Rust 通过立即退出,而不是允许这次内存访问继续发生并让程序往下执行,来保护你免受这类错误的影响。第九章会更详细地讨论 Rust 的错误处理机制,以及如何编写既可读又安全的代码,让程序既不会 panic也不会发生非法内存访问。</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch03-01-variables-and-mutability.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="ch03-03-how-functions-work.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="ch03-01-variables-and-mutability.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="ch03-03-how-functions-work.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-c2a407aa.js"></script>
<script src="clipboard-1626706a.min.js"></script>
<script src="highlight-abc7f01d.js"></script>
<script src="book-a0b12cfe.js"></script>
<!-- Custom JS scripts -->
<script src="ferris-2317480c.js"></script>
</div>
</body>
</html>