Skip to content

Commit a3d3c2a

Browse files
committed
update rust note
Signed-off-by: chang-ning <spiderpower02@gmail.com>
1 parent e523e36 commit a3d3c2a

2 files changed

Lines changed: 119 additions & 33 deletions

File tree

docs/notes/rust/rust_basic.rst

Lines changed: 2 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -395,39 +395,8 @@ that returned references remain valid. The compiler provides no help.
395395
Slices
396396
------
397397

398-
Slices are references to a contiguous sequence of elements. They're similar to
399-
C++20's ``std::span`` but are a fundamental part of Rust.
400-
401-
**C++ (std::span, C++20):**
402-
403-
.. code-block:: cpp
404-
405-
#include <span>
406-
#include <vector>
407-
408-
void print_slice(std::span<int> s) {
409-
for (int x : s) std::cout << x << " ";
410-
}
411-
412-
int main() {
413-
std::vector<int> v = {1, 2, 3, 4, 5};
414-
print_slice(std::span(v).subspan(1, 3)); // 2 3 4
415-
}
416-
417-
**Rust:**
418-
419-
.. code-block:: rust
420-
421-
fn print_slice(s: &[i32]) {
422-
for x in s {
423-
print!("{} ", x);
424-
}
425-
}
426-
427-
fn main() {
428-
let v = vec![1, 2, 3, 4, 5];
429-
print_slice(&v[1..4]); // 2 3 4
430-
}
398+
See :doc:`rust_container` for details on slices (``&[T]``), ``Vec<T>``, and
399+
fixed-size arrays (``[T; N]``).
431400

432401
The ``?`` Operator
433402
-------------------

docs/notes/rust/rust_container.rst

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,123 @@ return ``Option`` types, making it explicit when an element might not be found:
203203
println!("Length: {}, Capacity: {}", len, v.capacity());
204204
}
205205
206+
``Vec<T>`` vs Fixed-size Arrays ``[T; N]``
207+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
208+
209+
Rust has two main array types: ``Vec<T>`` (heap-allocated, growable) and
210+
``[T; N]`` (stack-allocated, fixed size known at compile time). C++ has the
211+
same distinction with ``std::vector<T>`` vs ``std::array<T, N>``.
212+
213+
**C++:**
214+
215+
.. code-block:: cpp
216+
217+
#include <array>
218+
#include <vector>
219+
220+
int main() {
221+
std::vector<uint8_t> rom; // heap, size determined at runtime
222+
rom.resize(0x4000);
223+
224+
std::array<uint8_t, 256> oam; // stack, size fixed at compile time
225+
226+
return 0;
227+
}
228+
229+
**Rust:**
230+
231+
.. code-block:: rust
232+
233+
fn main() {
234+
let rom: Vec<u8> = vec![0; 0x4000]; // heap, size determined at runtime
235+
236+
let oam: [u8; 256] = [0; 256]; // stack, size fixed at compile time
237+
}
238+
239+
Use ``Vec<T>`` when the size is unknown at compile time (e.g., loading ROM data
240+
from a file). Use ``[T; N]`` when the size is fixed by the hardware specification
241+
(e.g., PPU sprite memory is always 256 bytes).
242+
243+
Slices ``&[T]``
244+
~~~~~~~~~~~~~~~~
245+
246+
A slice ``&[T]`` is a borrowed view into a contiguous sequence of elements. It is
247+
the idiomatic way to pass arrays or vectors to functions without transferring
248+
ownership. In C++, the closest equivalent is ``std::span<T>`` (C++20) or passing
249+
``const T*`` with a length.
250+
251+
**C++:**
252+
253+
.. code-block:: cpp
254+
255+
#include <iostream>
256+
#include <span>
257+
#include <vector>
258+
259+
// C++20: std::span borrows a contiguous range
260+
void print_data(std::span<const uint8_t> data) {
261+
for (auto byte : data) {
262+
std::cout << (int)byte << " ";
263+
}
264+
std::cout << "\n";
265+
}
266+
267+
// Before C++20: pass pointer + length
268+
void print_data_legacy(const uint8_t* data, size_t len) {
269+
for (size_t i = 0; i < len; ++i) {
270+
std::cout << (int)data[i] << " ";
271+
}
272+
std::cout << "\n";
273+
}
274+
275+
int main() {
276+
std::vector<uint8_t> rom = {0x4E, 0x45, 0x53, 0x1A};
277+
print_data(rom); // pass vector as span
278+
print_data({rom.data(), 2}); // pass first 2 bytes
279+
return 0;
280+
}
281+
282+
**Rust:**
283+
284+
.. code-block:: rust
285+
286+
// &[u8] borrows a contiguous sequence — works with Vec, arrays, or other slices
287+
fn print_data(data: &[u8]) {
288+
for byte in data {
289+
print!("{} ", byte);
290+
}
291+
println!();
292+
}
293+
294+
fn main() {
295+
let rom: Vec<u8> = vec![0x4E, 0x45, 0x53, 0x1A];
296+
print_data(&rom); // Vec<u8> auto-borrows as &[u8]
297+
print_data(&rom[..2]); // pass first 2 bytes as a slice
298+
299+
let arr: [u8; 4] = [0x4E, 0x45, 0x53, 0x1A];
300+
print_data(&arr); // fixed-size array also works
301+
}
302+
303+
.. note::
304+
305+
Prefer ``&[T]`` over ``&Vec<T>`` in function parameters. A ``&[T]`` accepts
306+
both ``Vec<T>`` and fixed-size arrays ``[T; N]``, making the function more
307+
flexible. Returning ``&[T]`` from a method that owns a ``Vec<T>`` is also
308+
idiomatic:
309+
310+
.. code-block:: rust
311+
312+
struct Cartridge {
313+
prg_rom: Vec<u8>,
314+
}
315+
316+
impl Cartridge {
317+
// return &[u8] instead of &Vec<u8>
318+
pub fn prg_rom(&self) -> &[u8] {
319+
&self.prg_rom
320+
}
321+
}
322+
206323
HashMap
207324
-------
208325

0 commit comments

Comments
 (0)