-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathch07-03-paths-for-referring-to-an-item-in-the-module-tree.html
406 lines (351 loc) · 59.5 KB
/
ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
<!DOCTYPE HTML>
<html lang="uk" class="sidebar-visible no-js light">
<head>
<!-- Book generated using mdBook -->
<meta charset="UTF-8">
<title>Шлях для Доступу до Елементів у Дереві Модулів - Мова програмування 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 affix "><a href="title-page.html">Мова Програмування Rust</a></li><li class="chapter-item expanded affix "><a href="foreword.html">Передмова</a></li><li class="chapter-item expanded affix "><a href="ch00-00-introduction.html">Вступ</a></li><li class="chapter-item expanded "><a href="ch01-00-getting-started.html"><strong aria-hidden="true">1.</strong> Початок</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch01-01-installation.html"><strong aria-hidden="true">1.1.</strong> Встановлення</a></li><li class="chapter-item expanded "><a href="ch01-02-hello-world.html"><strong aria-hidden="true">1.2.</strong> Hello, World!</a></li><li class="chapter-item expanded "><a href="ch01-03-hello-cargo.html"><strong aria-hidden="true">1.3.</strong> Привіт, Cargo!</a></li></ol></li><li class="chapter-item expanded "><a href="ch02-00-guessing-game-tutorial.html"><strong aria-hidden="true">2.</strong> Програмування Гри Відгадайки</a></li><li class="chapter-item expanded "><a href="ch03-00-common-programming-concepts.html"><strong aria-hidden="true">3.</strong> Загальні Концепції Програмування</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch03-01-variables-and-mutability.html"><strong aria-hidden="true">3.1.</strong> Змінні і Мутабельність</a></li><li class="chapter-item expanded "><a href="ch03-02-data-types.html"><strong aria-hidden="true">3.2.</strong> Типи Даних</a></li><li class="chapter-item expanded "><a href="ch03-03-how-functions-work.html"><strong aria-hidden="true">3.3.</strong> Функції</a></li><li class="chapter-item expanded "><a href="ch03-04-comments.html"><strong aria-hidden="true">3.4.</strong> Коментарі</a></li><li class="chapter-item expanded "><a href="ch03-05-control-flow.html"><strong aria-hidden="true">3.5.</strong> Потік Виконання</a></li></ol></li><li class="chapter-item expanded "><a href="ch04-00-understanding-ownership.html"><strong aria-hidden="true">4.</strong> Розуміння Володіння</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch04-01-what-is-ownership.html"><strong aria-hidden="true">4.1.</strong> Що Таке Володіння?</a></li><li class="chapter-item expanded "><a href="ch04-02-references-and-borrowing.html"><strong aria-hidden="true">4.2.</strong> Посилання та Позичання</a></li><li class="chapter-item expanded "><a href="ch04-03-slices.html"><strong aria-hidden="true">4.3.</strong> Слайси</a></li></ol></li><li class="chapter-item expanded "><a href="ch05-00-structs.html"><strong aria-hidden="true">5.</strong> Використання Структур для Групування Пов'язаних Даних</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch05-01-defining-structs.html"><strong aria-hidden="true">5.1.</strong> Визначення та Створення Екземпляра Структури</a></li><li class="chapter-item expanded "><a href="ch05-02-example-structs.html"><strong aria-hidden="true">5.2.</strong> Приклад Програми з Використанням Структур</a></li><li class="chapter-item expanded "><a href="ch05-03-method-syntax.html"><strong aria-hidden="true">5.3.</strong> Синтаксис Методів</a></li></ol></li><li class="chapter-item expanded "><a href="ch06-00-enums.html"><strong aria-hidden="true">6.</strong> Енуми та Зіставлення зі Шаблоном</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch06-01-defining-an-enum.html"><strong aria-hidden="true">6.1.</strong> Визначення Енума</a></li><li class="chapter-item expanded "><a href="ch06-02-match.html"><strong aria-hidden="true">6.2.</strong> Конструкція Потоку Виконання match</a></li><li class="chapter-item expanded "><a href="ch06-03-if-let.html"><strong aria-hidden="true">6.3.</strong> Лаконічний Потік Виконання з if let</a></li></ol></li><li class="chapter-item expanded "><a href="ch07-00-managing-growing-projects-with-packages-crates-and-modules.html"><strong aria-hidden="true">7.</strong> Керування Щораз Більшими Проєктами із Пакетами, Крейтами та Модулями</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch07-01-packages-and-crates.html"><strong aria-hidden="true">7.1.</strong> Пакети та Крейти</a></li><li class="chapter-item expanded "><a href="ch07-02-defining-modules-to-control-scope-and-privacy.html"><strong aria-hidden="true">7.2.</strong> Визначення Модулів для Контролю Області Видимості та Приватності</a></li><li class="chapter-item expanded "><a href="ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html" class="active"><strong aria-hidden="true">7.3.</strong> Шлях для Доступу до Елементів у Дереві Модулів</a></li><li class="chapter-item expanded "><a href="ch07-04-bringing-paths-into-scope-with-the-use-keyword.html"><strong aria-hidden="true">7.4.</strong> Введення Шляхів до Області Видимості з Ключовим Словом use</a></li><li class="chapter-item expanded "><a href="ch07-05-separating-modules-into-different-files.html"><strong aria-hidden="true">7.5.</strong> Розподіл Модулів на Різні Файли</a></li></ol></li><li class="chapter-item expanded "><a href="ch08-00-common-collections.html"><strong aria-hidden="true">8.</strong> Звичайні Колекції</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch08-01-vectors.html"><strong aria-hidden="true">8.1.</strong> Зберігання Списків Значень з Векторами</a></li><li class="chapter-item expanded "><a href="ch08-02-strings.html"><strong aria-hidden="true">8.2.</strong> Зберігання Тексту у Кодуванні UTF-8 в Стрічках</a></li><li class="chapter-item expanded "><a href="ch08-03-hash-maps.html"><strong aria-hidden="true">8.3.</strong> Зберігання Ключів з Асоційованими Значеннями у Хеш-Мапах</a></li></ol></li><li class="chapter-item expanded "><a href="ch09-00-error-handling.html"><strong aria-hidden="true">9.</strong> Обробка Помилок</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch09-01-unrecoverable-errors-with-panic.html"><strong aria-hidden="true">9.1.</strong> Невідновлювані Помилки з panic!</a></li><li class="chapter-item expanded "><a href="ch09-02-recoverable-errors-with-result.html"><strong aria-hidden="true">9.2.</strong> Відновлювані Помилки з Result</a></li><li class="chapter-item expanded "><a href="ch09-03-to-panic-or-not-to-panic.html"><strong aria-hidden="true">9.3.</strong> panic! чи не panic!</a></li></ol></li><li class="chapter-item expanded "><a href="ch10-00-generics.html"><strong aria-hidden="true">10.</strong> Узагальнені Типи, Трейти та Часи Існування</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch10-01-syntax.html"><strong aria-hidden="true">10.1.</strong> Узагальнені Типи Даних</a></li><li class="chapter-item expanded "><a href="ch10-02-traits.html"><strong aria-hidden="true">10.2.</strong> Трейти: Визначення Спільної Поведінки</a></li><li class="chapter-item expanded "><a href="ch10-03-lifetime-syntax.html"><strong aria-hidden="true">10.3.</strong> Перевірка Коректності Посилань із Часами Існування</a></li></ol></li><li class="chapter-item expanded "><a href="ch11-00-testing.html"><strong aria-hidden="true">11.</strong> Написання Автоматизованих Тестів</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch11-01-writing-tests.html"><strong aria-hidden="true">11.1.</strong> Як Писати Тести</a></li><li class="chapter-item expanded "><a href="ch11-02-running-tests.html"><strong aria-hidden="true">11.2.</strong> Керування Запуском Тестів</a></li><li class="chapter-item expanded "><a href="ch11-03-test-organization.html"><strong aria-hidden="true">11.3.</strong> Організація Тестів</a></li></ol></li><li class="chapter-item expanded "><a href="ch12-00-an-io-project.html"><strong aria-hidden="true">12.</strong> Проєкт з Вводом/Виводом: Створення Програми з Інтерфейсом Командного Рядка</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch12-01-accepting-command-line-arguments.html"><strong aria-hidden="true">12.1.</strong> Приймання Аргументів Командного Рядка</a></li><li class="chapter-item expanded "><a href="ch12-02-reading-a-file.html"><strong aria-hidden="true">12.2.</strong> Читання Файлу</a></li><li class="chapter-item expanded "><a href="ch12-03-improving-error-handling-and-modularity.html"><strong aria-hidden="true">12.3.</strong> Рефакторинг для Покращення Модульності та Обробки Помилок</a></li><li class="chapter-item expanded "><a href="ch12-04-testing-the-librarys-functionality.html"><strong aria-hidden="true">12.4.</strong> Розробка Функціонала Бібліотеки із Test-Driven Development</a></li><li class="chapter-item expanded "><a href="ch12-05-working-with-environment-variables.html"><strong aria-hidden="true">12.5.</strong> Робота зі Змінними Середовища</a></li><li class="chapter-item expanded "><a href="ch12-06-writing-to-stderr-instead-of-stdout.html"><strong aria-hidden="true">12.6.</strong> Написання Повідомлень про Помилки у Помилковий Вивід замість Стандартного Виводу</a></li></ol></li><li class="chapter-item expanded "><a href="ch13-00-functional-features.html"><strong aria-hidden="true">13.</strong> Функціональні Можливості Мови: Ітератори та Замикання</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch13-01-closures.html"><strong aria-hidden="true">13.1.</strong> Замикання: Анонімні Функції, що Захоплюють Своє Середовище</a></li><li class="chapter-item expanded "><a href="ch13-02-iterators.html"><strong aria-hidden="true">13.2.</strong> Обробка Послідовностей Елементів з Ітераторами</a></li><li class="chapter-item expanded "><a href="ch13-03-improving-our-io-project.html"><strong aria-hidden="true">13.3.</strong> Покращення Нашого Проєкту з Вводом/Виводом</a></li><li class="chapter-item expanded "><a href="ch13-04-performance.html"><strong aria-hidden="true">13.4.</strong> Порівняння Швидкодії: Цикли Проти Ітераторів</a></li></ol></li><li class="chapter-item expanded "><a href="ch14-00-more-about-cargo.html"><strong aria-hidden="true">14.</strong> Більше про Cargo та Crates.io</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch14-01-release-profiles.html"><strong aria-hidden="true">14.1.</strong> Налаштування Збірок з Release Профілями</a></li><li class="chapter-item expanded "><a href="ch14-02-publishing-to-crates-io.html"><strong aria-hidden="true">14.2.</strong> Публікація Крейта на Crates.io</a></li><li class="chapter-item expanded "><a href="ch14-03-cargo-workspaces.html"><strong aria-hidden="true">14.3.</strong> Робочі Області Cargo</a></li><li class="chapter-item expanded "><a href="ch14-04-installing-binaries.html"><strong aria-hidden="true">14.4.</strong> Встановлення Двійкових Файлів з cargo install</a></li><li class="chapter-item expanded "><a href="ch14-05-extending-cargo.html"><strong aria-hidden="true">14.5.</strong> Розширення Cargo із Користувацькими Командами</a></li></ol></li><li class="chapter-item expanded "><a href="ch15-00-smart-pointers.html"><strong aria-hidden="true">15.</strong> Розумні Вказівники</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch15-01-box.html"><strong aria-hidden="true">15.1.</strong> Використання Box<T> для Вказування на Дані в Купі</a></li><li class="chapter-item expanded "><a href="ch15-02-deref.html"><strong aria-hidden="true">15.2.</strong> Ставлення до Розумних Вказівників як до Звичайних Посилань з Трейтом Deref</a></li><li class="chapter-item expanded "><a href="ch15-03-drop.html"><strong aria-hidden="true">15.3.</strong> Виконання Коду при Очищенні з Трейтом Drop</a></li><li class="chapter-item expanded "><a href="ch15-04-rc.html"><strong aria-hidden="true">15.4.</strong> Rc<T> - Розумний Вказівник з Лічильником Посилань</a></li><li class="chapter-item expanded "><a href="ch15-05-interior-mutability.html"><strong aria-hidden="true">15.5.</strong> RefCell<T> та Шаблон Внутрішньої Мутабельності</a></li><li class="chapter-item expanded "><a href="ch15-06-reference-cycles.html"><strong aria-hidden="true">15.6.</strong> Цикли Посилань Можуть Спричинити Витік Пам'яті</a></li></ol></li><li class="chapter-item expanded "><a href="ch16-00-concurrency.html"><strong aria-hidden="true">16.</strong> Безстрашна Конкурентність</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch16-01-threads.html"><strong aria-hidden="true">16.1.</strong> Використання Потоків для Одночасного Виконання Коду</a></li><li class="chapter-item expanded "><a href="ch16-02-message-passing.html"><strong aria-hidden="true">16.2.</strong> Застосування Обміну Повідомлень для Передавання Даних між Потоками</a></li><li class="chapter-item expanded "><a href="ch16-03-shared-state.html"><strong aria-hidden="true">16.3.</strong> Конкурентність зі Спільним Станом</a></li><li class="chapter-item expanded "><a href="ch16-04-extensible-concurrency-sync-and-send.html"><strong aria-hidden="true">16.4.</strong> Розширювана Конкурентність із Трейтами Sync та Send</a></li></ol></li><li class="chapter-item expanded "><a href="ch17-00-oop.html"><strong aria-hidden="true">17.</strong> Особливості Об'єктоорієнтованого Програмування в Rust</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch17-01-what-is-oo.html"><strong aria-hidden="true">17.1.</strong> Характеристики Об'єктоорієнтованих Мов</a></li><li class="chapter-item expanded "><a href="ch17-02-trait-objects.html"><strong aria-hidden="true">17.2.</strong> Використання Трейт-Об'єктів, які Допускають Значення Різних Типів</a></li><li class="chapter-item expanded "><a href="ch17-03-oo-design-patterns.html"><strong aria-hidden="true">17.3.</strong> Реалізація Об'єктоорієнтованого Шаблону Проєктування</a></li></ol></li><li class="chapter-item expanded "><a href="ch18-00-patterns.html"><strong aria-hidden="true">18.</strong> Шаблони та Зіставлення Шаблонів</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch18-01-all-the-places-for-patterns.html"><strong aria-hidden="true">18.1.</strong> Усі Місця Можливого Використання Шаблонів</a></li><li class="chapter-item expanded "><a href="ch18-02-refutability.html"><strong aria-hidden="true">18.2.</strong> Спростовуваність: Чи Може Шаблон Бути Невідповідним</a></li><li class="chapter-item expanded "><a href="ch18-03-pattern-syntax.html"><strong aria-hidden="true">18.3.</strong> Синтаксис Шаблонів</a></li></ol></li><li class="chapter-item expanded "><a href="ch19-00-advanced-features.html"><strong aria-hidden="true">19.</strong> Просунуті Можливості</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch19-01-unsafe-rust.html"><strong aria-hidden="true">19.1.</strong> Небезпечний Rust</a></li><li class="chapter-item expanded "><a href="ch19-03-advanced-traits.html"><strong aria-hidden="true">19.2.</strong> Поглиблено про Трейти</a></li><li class="chapter-item expanded "><a href="ch19-04-advanced-types.html"><strong aria-hidden="true">19.3.</strong> Поглиблено про Типи</a></li><li class="chapter-item expanded "><a href="ch19-05-advanced-functions-and-closures.html"><strong aria-hidden="true">19.4.</strong> Поглиблено про Функції та Замикання</a></li><li class="chapter-item expanded "><a href="ch19-06-macros.html"><strong aria-hidden="true">19.5.</strong> Макроси</a></li></ol></li><li class="chapter-item expanded "><a href="ch20-00-final-project-a-web-server.html"><strong aria-hidden="true">20.</strong> Останній Проєкт: Збірка Багатопотокового Вебсервера</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="ch20-01-single-threaded.html"><strong aria-hidden="true">20.1.</strong> Збірка Однопотокового Вебсервера</a></li><li class="chapter-item expanded "><a href="ch20-02-multithreaded.html"><strong aria-hidden="true">20.2.</strong> Перетворюємо Наш Однопотоковий Сервер на Багатопотоковий</a></li><li class="chapter-item expanded "><a href="ch20-03-graceful-shutdown-and-cleanup.html"><strong aria-hidden="true">20.3.</strong> Плавне Вимкнення та Очищення</a></li></ol></li><li class="chapter-item expanded "><a href="appendix-00.html"><strong aria-hidden="true">21.</strong> Додатки</a></li><li><ol class="section"><li class="chapter-item expanded "><a href="appendix-01-keywords.html"><strong aria-hidden="true">21.1.</strong> A - Ключові Слова</a></li><li class="chapter-item expanded "><a href="appendix-02-operators.html"><strong aria-hidden="true">21.2.</strong> B - Оператори та Символи</a></li><li class="chapter-item expanded "><a href="appendix-03-derivable-traits.html"><strong aria-hidden="true">21.3.</strong> C - Похідні Трейти</a></li><li class="chapter-item expanded "><a href="appendix-04-useful-development-tools.html"><strong aria-hidden="true">21.4.</strong> D - Корисні Інструменти Розробки</a></li><li class="chapter-item expanded "><a href="appendix-05-editions.html"><strong aria-hidden="true">21.5.</strong> E - Видання</a></li><li class="chapter-item expanded "><a href="appendix-06-translation.html"><strong aria-hidden="true">21.6.</strong> F - Переклади Книги</a></li><li class="chapter-item expanded "><a href="appendix-07-nightly-rust.html"><strong aria-hidden="true">21.7.</strong> G - як Розробляється Rust і "Нічний Rust"</a></li></ol></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">Мова програмування 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="Шлях-для-Доступу-до-Елементів-у-Дереві-Модулів"><a class="header" href="#Шлях-для-Доступу-до-Елементів-у-Дереві-Модулів">Шлях для Доступу до Елементів у Дереві Модулів</a></h2>
<p>Щоб вказати Rust, де шукати елемент у дереві модулів, ми використовуємо шляхи так само як ми використовуємо шляхи для навігації по файловій системі. Щоб викликати функцію, ми повинні знати її шлях.</p>
<p>Шлях може приймати дві форми:</p>
<ul>
<li><em>Aбсолютний шлях</em> це повний шлях, що починається в кореневій директорії крейту; для коду від зовнішнього крейту, абсолютний шлях починається з назви крейту, і для коду з поточного ящика починається з рядка <code>crate</code>.</li>
<li><em>Відносний шлях</em> починається у поточному модулі і використовує <code>self</code>, <code>super</code> чи ідентифікатор поточного модуля.</li>
</ul>
<p>І абсолютні, і відносні шляхи складаються з одного чи кількох ідентифікаторів, розділених подвійною двокрапкою (<code>::</code>).</p>
<p>Повернімося до Блоку коду 7-1. Скажімо, ми хочемо викликати функцію <code>add_to_waitlist</code>. Це те саме, що й запитати: який шлях до функції <code>add_to_waitlist</code>? Блок коду 7-3 містить Блок коду 7-1, але деякі з модулів та функцій прибрані.</p>
<p>Ми покажемо два способи викликати функцію <code>add_to_waitlist</code> з нової функції <code>eat_at_restaurant</code>, визначеної в корені крейта. Ці шляхи є правильними, але залишилася інша проблема, яка перешкоджає компілюванню цього прикладу "як є". Ми пояснимо, чому, трохи пізніше.</p>
<p>Функція <code>eat_at_restaurant</code> є частиною публічного API нашого бібліотечного крейта, тому ми позначимо її ключевим словом <code>pub</code>. Детальніше про <code>pub</code> йтиметься у підрозділі <a href="ch07-03-paths-for-referring-to-an-item-in-the-module-tree.html#exposing-paths-with-the-pub-keyword">"Надання доступу до шляхів за допомогою ключового слова <1>pub</1></a><!-- ignore --> .</p>
<p><span class="filename">Файл: src/lib.rs</span></p>
<pre><code class="language-rust ignore does_not_compile">mod front_of_house {
mod hosting {
fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
// Relative path
front_of_house::hosting::add_to_waitlist();
}
</code></pre>
<p><span class="caption">Блок коду 7-3: виклик функції <code>add_to_waitlist</code> за допомогою абсолютного та відносного шляхів</span></p>
<p>Коли ми вперше ми викликаємо функцію <code>add_to_waitlist</code> в <code>eat_at_restaurant</code>, то використовуємо абсолютний шлях. Функція <code>add_to_waitlist</code> визначена у тому ж крейті, що й <code>eat_at_restaurant</code>, тобто ми можемо використати ключове слово <code>crate</code> на початку абсолютного шляху. Потім ми додаємо кожен з вкладених модулів, доки не не вкажемо весь шлях до <code>add_to_waitlist</code>. Уявіть собі файлову систему з такою ж структурою: ми повинні вказати шлях <code>/front_of_house/hosting/add_to_waitlist</code>, щоб запустити програму <code>add_to_waitlist</code>; використання назви <code>crate</code>, щоб почати з кореня, схожий на використання <code>/</code>, щоб почати шлях з кореня файлової системи у вашій оболонці.</p>
<p>Коли ми вдруге викликаємо <code>add_to_waitlist</code> у <code>eat_at_restaurant</code>, то використовуємо відносний шлях. Шлях починається з <code>front_of_house</code>, назви модуля, визначеного на тому ж рівні дерева модулів, що й <code>eat_at_restaurant</code>. Тут аналогом з файлової системи буде використання шляху <code>front_of_house/hosting/add_to_waitlist</code>. Початок з назви модуля означає, що шлях є відносним.</p>
<p>Рішення, використовувати відносний або абсолютний шлях, вам доведеться робити, виходячи з від вашого проєкту, і залежить від того, чи код, що визначає елемент, окремо від коду, що використовує його, чи разом. Наприклад, якщо ми перемістимо модуль <code>front_of_house</code> і функцію <code>eat_at_restaurant</code> у модуль <code>customer_experience</code>, нам знадобиться оновити абсолютний шлях до <code>add_to_waitlist</code>, але відносний шлях усе ще буде коректним. Однак, якби ми перенесли функцію <code>eat_at_restaurant</code> окремо до модуля з назвою <code>dining</code>, абсолютний шлях до виклику <code>add_to_waitlist</code> залишаться таким самим, але відносний шлях треба буде оновити. Загалом, ми вважаємо за краще вказувати абсолютні шляхи, тому що з більшою ймовірністю ми захочемо перемістити код визначення та виклики елементів незалежно один від одного.</p>
<p>Спробуймо скомпілювати Блок коду 7-3 і дізнатися, чому він досі не компілюється! Помилка, що ми отримуємо, показана у Блоці коду 7-4.</p>
<pre><code class="language-console">$ cargo build
Compiling restaurant v0.1.0 (file:///projects/restaurant)
error[E0603]: module `hosting` is private
--> src/lib.rs:9:28
|
9 | crate::front_of_house::hosting::add_to_waitlist();
| ^^^^^^^ private module
|
note: the module `hosting` is defined here
--> src/lib.rs:2:5
|
2 | mod hosting {
| ^^^^^^^^^^^
error[E0603]: module `hosting` is private
--> src/lib.rs:12:21
|
12 | front_of_house::hosting::add_to_waitlist();
| ^^^^^^^ private module
|
note: the module `hosting` is defined here
--> src/lib.rs:2:5
|
2 | mod hosting {
| ^^^^^^^^^^^
For more information about this error, try `rustc --explain E0603`.
error: could not compile `restaurant` due to 2 previous errors
</code></pre>
<p><span class="caption">Блок коду 7-4: помилки компілятора при збірці коду в Блоці коду 7-3</span></p>
<p>Повідомлення про помилки кажуть, що модуль <code>hosting</code> є приватним. Іншими словами, ми маємо коректні шляхи для модуля <code>hosting</code> і функції <code>add_to_waitlist</code>, але Rust не дозволяє нам використовувати їх, бо немає доступу до приватних частин. У Rust усі елементи (функції, методи, структури, енуми, модулі і константи) за замовчуванням є приватними в батьківських модулях. Якщо ви хочете зробити елемент на кшталт функції чи структури приватним, то розміщуєте його у модулі.</p>
<p>Елементи батьківського модуля не можуть використовувати приватні елементи дочірніх модулів, але елементи дочірніх модулів можуть використовувати елементи у модулях-предках. Так зроблено, щоб дочірні модулі огортали і ховали деталі своєї реалізації, але дочірні модулі можуть бачити контекст, у якому їх визначено. Щоб розвинути нашу метафору, уявіть собі правила приватності як бек-офіс ресторану: те, що там відбувається, недоступно для клієнтів ресторану, але менеджери можуть бачити і робити все у ресторані, яким вони керують.</p>
<p>У Rust вирішено зробити модульну систему, де деталі реалізації є прихованими за замовчуванням. Таким чином, ви знаєте, які частини внутрішнього коду ви можете змінити, не зламавши зовнішній код. Однак Rust надає вам можливість виставити внутрішні частини коду дочірніх модулів для зовнішніх модулів-предків за допомогою ключового слова <code>pub</code>, щоб зробити елемент публічним.</p>
<h3 id="Надання-Публічного-Доступу-до-Шляхів-із-Ключовим-Словом-pub"><a class="header" href="#Надання-Публічного-Доступу-до-Шляхів-із-Ключовим-Словом-pub">Надання Публічного Доступу до Шляхів із Ключовим Словом <code>pub</code></a></h3>
<p>Повернімося до помилки у Блоці коду 7-4, яка каже нам, що модуль <code>hosting</code> є приватним. Ми хочемо, щоб функція <code>eat_at_restaurant</code> в батьківському модулі мала доступ до функції <code>add_to_waitlist</code> в дочірньому модулі, тож ми позначили модуль <code>hosting</code> за допомогою ключового слова <code>pub</code>, як показано в Блоці коду 7-5.</p>
<p><span class="filename">Файл: src/lib.rs</span></p>
<pre><code class="language-rust ignore does_not_compile">mod front_of_house {
pub mod hosting {
fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
// Relative path
front_of_house::hosting::add_to_waitlist();
}
</code></pre>
<p><span class="caption">Блок коду 7-5: проголошення модуля <code>hosting</code> як <code>pub</code>, щоб використовувати його з <code>eat_at_restaurant</code></span></p>
<p>На жаль, код у Блоці коду 7-5 все ще призводить до помилки, як це показано в Блоці коду 7-6.</p>
<pre><code class="language-console">$ cargo build
Compiling restaurant v0.1.0 (file:///projects/restaurant)
error[E0603]: function `add_to_waitlist` is private
--> src/lib.rs:9:37
|
9 | crate::front_of_house::hosting::add_to_waitlist();
| ^^^^^^^^^^^^^^^ private function
|
note: the function `add_to_waitlist` is defined here
--> src/lib.rs:3:9
|
3 | fn add_to_waitlist() {}
| ^^^^^^^^^^^^^^^^^^^^
error[E0603]: function `add_to_waitlist` is private
--> src/lib.rs:12:30
|
12 | front_of_house::hosting::add_to_waitlist();
| ^^^^^^^^^^^^^^^ private function
|
note: the function `add_to_waitlist` is defined here
--> src/lib.rs:3:9
|
3 | fn add_to_waitlist() {}
| ^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0603`.
error: could not compile `restaurant` due to 2 previous errors
</code></pre>
<p><span class="caption">Блок коду 7-6: помилки компілятора від збірки коду у Блоці коду 7-5</span></p>
<p>Що сталося? Додавання ключового слова <code>pub</code> перед <code>mod hosting</code> робить модуль публічним. Після цієї зміни, якщо ми маємо доступ <code>front_of_house</code>, ми можемо отримати доступ до <code>hosting</code>. Але <em>вміст</em> <code>hosting</code> все ще є приватним; зробивши модуль публічним, ми робимо публічним його вміст. Ключове слово <code>pub</code> для модуля дозволяє коду в модулях-предках тільки посилатися на нього, а не мати доступ до його внутрішнього коду. Оскільки модулі є контейнерами, ми багато не зробимо, лише зробивши модуль публічним; ми маємо піти далі і також зробити ще один або більше елементів модуля публічними.</p>
<p>Помилки у Блоці коду 7-6 кажуть, що функція <code>add_to_waitlist</code> є приватною. Правила приватності застосовуються до структур, енумів, функцій і методів, як і до модулів.</p>
<p>Також зробімо публічною функцію <code>add_to_waitlist</code>, додавши ключове слово <code>pub</code> перед її визначенням, як у Блоці коду 7-7.</p>
<p><span class="filename">Файл: src/lib.rs</span></p>
<pre><code class="language-rust noplayground test_harness">mod front_of_house {
pub mod hosting {
pub fn add_to_waitlist() {}
}
}
pub fn eat_at_restaurant() {
// Absolute path
crate::front_of_house::hosting::add_to_waitlist();
// Relative path
front_of_house::hosting::add_to_waitlist();
}
</code></pre>
<p><span class="caption">Блок коду 7-7: Додавання ключового слова <code>pub</code> до <code>mod hosting</code> і <code>fn add_to_waitlist</code> дозволяє нам викликати функцію з <code>eat_at_restaurant</code></span></p>
<p>Тепер код скомпілюється! Щоб побачити, чому додавання ключового слова <code>pub</code> дозволяє нам використовувати ці шляхи у <code>add_to_waitlist</code> відповідно до правил приватності, розгляньмо абсолютні та відносні шляхи.</p>
<p>Абсолютний шлях ми починаємо з <code>crate</code>, кореня дерева модулів нашого крейта. Модуль <code>front_of_house</code> визначено в корені крейта. Оскільки функція <code>eat_at_restaurant</code> визначена в тому ж модулі, що й <code>front_of_house</code> (тобто, <code>eat_at_restaurant</code> та <code>front_of_house</code> є сестрами), то поки <code>front_of_house</code> не є публічним, ми можемо посилатися на <code>front_of_house</code> лише з <code>eat_at_restaurant</code>. Наступний модуль <code>hosting</code> позначений як <code>pub</code>. Ми маємо доступ до батьківського модуля <code>hosting</code>, тож маємо доступ до <code>hosting</code>. Нарешті, функція <code>add_to_waitlist</code> позначена як <code>pub</code> і ми маємо доступ до її батьківського модуля, тож виклик функції працює!</p>
<p>У відносному шляху логіка така ж сама як і в абсолютному, окрім першого кроку: замість починати з кореня крейта, шлях починається з <code>front_of_house</code>. Модуль <code>front_of_house</code> визначено в тому ж модулі, що й <code>eat_at_restaurant</code>, тому відносний шлях, що починається з модуля, в якому визначено <code>eat_at_restaurant</code>, працює. Потім, оскільки <code>hosting</code> і <code>add_to_waitlist</code> позначені як <code>pub</code>, решта шляху працює, і цей виклик функції - коректний!</p>
<p>Якщо ви плануєте поділитися своєю бібліотекою, щоб інші проєкти могли використовувати ваш код, ваш публічний API - це ваш контракт з користувачами вашого крейта, який визначає, як вони можуть взаємодіяти з вашим кодом. Існує багато міркувань щодо управління змінами у вашому публічному API для полегшення залежності від Вашого крейта. Ці міркування не лежать за межами цієї книжки; якщо вам цікава ця тема, дивіться <a href="https://rust-lang.github.io/api-guidelines/">Керівництво з API Rust</a>.</p>
<blockquote>
<h4 id="Кращі-Практики-для-Пакетів-з-Двійковим-Крейтом-і-Бібліотекою"><a class="header" href="#Кращі-Практики-для-Пакетів-з-Двійковим-Крейтом-і-Бібліотекою">Кращі Практики для Пакетів з Двійковим Крейтом і Бібліотекою</a></h4>
<p>Ми згадували, що пакунок може містити одночасно корінь як двійкового крейта <em>src/main.rs</em>, так і корінь бібліотечного крейта <em>src/lib.rs</em>, і обидва крейти матимуть за замовчуванням назву пакету. Зазвичай, пакунки, створені за таким шаблоном, з бібліотекою і двійковим крейтом, матимуть у двійковому крейті лише код, потрібний для запуску виконуваного коду з бібліотечного крейта. Це дозволяє іншим проєктам отримувати максимум функціоналу, який надає пакунок, бо бібліотечний крейт можна використовувати спільно.</p>
<p>Дерево модулів має бути визначеним в <em>src/lib.rs</em>. Тоді будь-які публічні елементи можна використовувати у двійковому крейті, починаючи шлях з назви пакунку. Двійковий крейт стає таким самим користувачем бібліотечного крейта, як і абсолютно зовнішній крейт, що використовує бібліотечний крейт: він може користуватися лише публічним API. Це допомагає вам розробити хороший API; ви не лише його автор, але також і користувач!</p>
<p>У <a href="ch12-00-an-io-project.html">Розділі 12</a><!-- ignore -->ми покажемо цю практику організації крейта у програмі командного рядка, що міститиме як двійковий крейт, так і бібліотечний крейт.</p>
</blockquote>
<h3 id="Початок-Відносних-Шляхів-з-super"><a class="header" href="#Початок-Відносних-Шляхів-з-super">Початок Відносних Шляхів з <code>super</code></a></h3>
<p>Ми можемо створювати відносні шляхи, які починаються в батьківському модулі, а не в поточному чи корені крейта, застосувавши <code>super</code> на початку шляху. Це схоже на <code>..</code> на початку шляху в файловій системі. За допомогою <code>super</code> ми можемо посилатися на елемент, що, як ми знаємо, знаходиться в батьківському модулі, що спрощує зміну дерева модулів, коли модуль є тісно пов'язаним із батьком, але батьківський елемент може бути переміщений в інше місця дерева модулів.</p>
<p>Розглянемо код у Блоці коду 7-8, який моделює ситуацію, в якій шеф-кухар виправляє неправильне замовлення і особисто приносить його клієнту. Функція <code>fix_incorrect_order</code>, визначена у модулі <code>back_of_house</code> викликає функцію <code>deliver_order</code>, визначену в батьківському модулі, вказавши шлях до <code>deliver_order</code>, починаючи з <code>super</code>:</p>
<p><span class="filename">Файл: src/lib.rs</span></p>
<pre><code class="language-rust noplayground test_harness">fn deliver_order() {}
mod back_of_house {
fn fix_incorrect_order() {
cook_order();
super::deliver_order();
}
fn cook_order() {}
}
</code></pre>
<p><span class="caption">Блок коду 7-8: виклик функції за допомогою відносного шляху, що починається з <code>super</code></span></p>
<p>Функція <code>fix_incorrect_order</code> знаходиться в модулі <code>back_of_house</code>, тож ми можемо використатися <code>super</code>, щоб перейти до батьківсього модуля <code>back_of_house</code>, який у цьому випадку є коренем, <code>crate</code>. Звідси ми шукаємо <code>deliver_order</code> і знаходимо її. Успіх! Ми гадаємо, що модуль <code>back_of_house</code> і функція <code>deliver_order</code> найімовірніше залишатимуться у такому відношенні одне до одного і будуть переміщені разом, якщо ми вирішимо реорганізувати дерево модулів крейта. Таким чином, ми скористалися <code>super</code>, щоб мати менше місць, де треба буде для оновлювати код у майбутньому, якщо цей код перемістять в інший модуль.</p>
<h3 id="Робимо-Структури-та-Енуми-Публічними"><a class="header" href="#Робимо-Структури-та-Енуми-Публічними">Робимо Структури та Енуми Публічними</a></h3>
<p>Також ми можемо використовувати <code>pub</code> для визначення структур та енумів публічними, але є додаткові особливості використання <code>pub</code> зі структурами та енумами. Якщо ми використовуємо <code>pub</code> перед визначенням структури, ми робимо структуру публічною, але поля структури все одно будуть приватними. Ми можемо зробити публічним чи ні кожне поле окремо в кожному конкретному випадку. У Блоці коду 7-9 ми визначили публічну структуру <code>back_of_house::Breakfast</code> з публічним полем <code>toast</code>, але приватним полем <code>seasonal_fruit</code>. Це моделює ситуацію в ресторані, коли покупець може обрати тип хліба, що додається до їжі, але кухар вирішує, які фрукти йдуть до їжі залежно від сезону і наявності. Доступні фрукти швидко змінюються, тому клієнти не можуть вибрати фрукти і навіть побачити, які фрукти вони отримають.</p>
<p><span class="filename">Файл: src/lib.rs</span></p>
<pre><code class="language-rust noplayground">mod back_of_house {
pub struct Breakfast {
pub toast: String,
seasonal_fruit: String,
}
impl Breakfast {
pub fn summer(toast: &str) -> Breakfast {
Breakfast {
toast: String::from(toast),
seasonal_fruit: String::from("peaches"),
}
}
}
}
pub fn eat_at_restaurant() {
// Order a breakfast in the summer with Rye toast
let mut meal = back_of_house::Breakfast::summer("Rye");
// Change our mind about what bread we'd like
meal.toast = String::from("Wheat");
println!("I'd like {} toast please", meal.toast);
// The next line won't compile if we uncomment it; we're not allowed
// to see or modify the seasonal fruit that comes with the meal
// meal.seasonal_fruit = String::from("blueberries");
}
</code></pre>
<p><span class="caption">Блок коду 7-9: структура, деякі поля якої є публічними, а деякі приватними</span></p>
<p>Оскільки поле <code>toast</code> у структурі <code>back_of_house::Breakfast</code> є публічним, у <code>eat_at_restaurant</code> ми можемо писати та читати поле <code>toast</code>, використовуючи точку. Зверніть увагу, що ми не можемо використовувати поле <code>seasonal_fruit</code> у <code>eat_at_restaurant</code>, тому що <code>seasonal_fruit</code> є приватним. Спробуйте розкоментувати рядок, що змінює значення поля <code>seasonal_fruit</code>, щоб подивитися, яку помилку ви отримуєте!</p>
<p>Крім того, зауважте, що оскільки <code>back_of_house::Breakfast</code> має приватне поле, структура має надавати публічну асоційовану функцію, що створює екземпляр <code>Breakfast</code> (тут ми назвали її <code>summer</code>). Якби <code>Breakfast</code> не мав такої функції, ми не могли б створити екземпляр <code>Breakfast</code> у <code>eat_at_restaurant</code>, бо не могли б виставити значення приватного поля <code>seasonal_fruit</code> у <code>eat_at_restaurant</code>.</p>
<p>На відміну від цього, якщо ми робимо енум публічним, усі його варіанти є публічними. Потрібно лише одне ключове слово <code>pub</code> перед <code>enum</code>, як показано в Блоці коду 7-10.</p>
<p><span class="filename">Файл: src/lib.rs</span></p>
<pre><code class="language-rust noplayground">mod back_of_house {
pub enum Appetizer {
Soup,
Salad,
}
}
pub fn eat_at_restaurant() {
let order1 = back_of_house::Appetizer::Soup;
let order2 = back_of_house::Appetizer::Salad;
}
</code></pre>
<p><span class="caption">Блок коду 7-10: позначення енума публічним робить публічними усі його варіанти</span></p>
<p>Оскільки ми зробили енум <code>Appetizer</code> публічним, то можемо використовувати варіанти <code>Soup</code> та <code>Salad</code> у <code>eat_at_restaurant</code>.</p>
<p>Енуми не дуже корисні, коли їхні варіанти не є публічними; було б набридливим анотувати всі варіанти енуму як <code>pub</code> у будь-якому випадку, то за замовчуванням варіанти переліку є публічними. Структури часто є корисними без публічних полів, тож поля структур слідують загальному правилу, що все є приватним за замовчуванням, якщо не анотовано як <code>pub</code>.</p>
<p>Є ще одна ситуація, пов’язана з <code>pub</code>, про яку ми не розповіли, і це остання деталь системи модулів: ключове слово <code>use</code>. Ми спершу розповімо про <code>use</code>, а потім покажемо, як комбінувати <code>pub</code> і <code>use</code>.</p>
</main>
<nav class="nav-wrapper" aria-label="Page navigation">
<!-- Mobile navigation buttons -->
<a rel="prev" href="ch07-02-defining-modules-to-control-scope-and-privacy.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="ch07-04-bringing-paths-into-scope-with-the-use-keyword.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="ch07-02-defining-modules-to-control-scope-and-privacy.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="ch07-04-bringing-paths-into-scope-with-the-use-keyword.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>