@@ -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