ProgrammatieBackend ontwikkelaar

Hoe werkt het slice-mechanisme in Rust, welke types slices bestaan er, hoe wordt de veiligheid gewaarborgd en wat gebeurt er als je buiten de slice probeert te gaan?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

Slice in Rust is een dynamische weergave van een deel van een collectie waarvan de elementen aaneengeschakeld in het geheugen zijn opgeslagen. Een typisch voorbeeld van een slice is &[T] of &mut [T]. Slices bezitten geen gegevens, ze verwijzen naar een externe buffer. Alle slices hebben een lengte die samen met de referentie wordt opgeslagen.

Belangrijkste types:

  • &[T] — onveranderlijk slice
  • &mut [T] — veranderlijk slice
  • Voor strings: &str (feitelijk een byte-slice, altijd geldige UTF-8)

De veiligheid van slices wordt gewaarborgd op compileertijd en runtime: elke poging om een element buiten de slice te benaderen, resulteert in panic tijdens uitvoering; er zal geen onherstelbare geheugenfout zoals in C/C++ optreden.

Voorbeeld:

let v = vec![1, 2, 3, 4, 5]; let s: &[i32] = &v[1..4]; // slice dat verwijst naar elementen 2, 3, 4 println!("{:?}", s); // [2, 3, 4] // s[3]; // panic! (buiten de grenzen)

Misleidende vraag

Kunnen slices leeg zijn? Wat is het verschil tussen een lege slice en None?

Antwoord: Ja, slices kunnen leeg zijn (&[]), dit betekent een verwijzing naar een deel van de gegevens met nul lengte, maar is geen equivalent van None. Een lege slice is veilig om te gebruiken, terwijl Option<&[T]> dient om te onderscheiden "is er überhaupt een slice".

Voorbeeld:

let s: &[i32] = &[]; assert!(s.is_empty()); // Option<&[i32]> wordt gebruikt als de slice misschien helemaal niet bestaat.

Voorbeelden van echte fouten door gebrek aan kennis over de subtiliteiten van het onderwerp


Verhaal

In een grote logdienst nam een programmeur een slice op basis van een dynamisch berekende range van gebruikersgegevens. Bij een foutieve berekening van de slice (bijvoorbeeld start > end of als end > len), werkte de code in tests, maar veroorzaakte het op productie "panic" en stopte de applicatie in piekbelastingen.


Verhaal

In een interne bibliotheek voor concurrent hashing gebruikten ze &mut [T] en meerdere threads namen parallel verschillende slices van een enkele array. Eén thread wijzigde de slice, terwijl een andere een andere slice van hetzelfde geheugen nam. De applicatie compileerde, maar door verkeerde delingen konden er UB ontstaan door onveilige code (gebruik van unsafe), als de slices toch overlappen.


Verhaal

In een systeemparser voor netwerkpakketten werd een slice op onveilige wijze gemaakt (raw pointer en from_raw_parts). De ontwikkelaar vergat de juistheid van de lengte van het binnenkomende pakket te controleren. Dit resulteerde in een poging om buiten de grenzen te lezen, wat leidde tot een falen van de applicatie en een kwetsbaarheid (potentieel OOB-toegang), die verholpen had kunnen worden door het juiste gebruik van veilige slices.