A slice in Rust is a dynamic representation of a part of a collection where elements are stored in contiguous memory. A typical example of a slice is &[T] or &mut [T]. Slices do not own the data; they reference an external buffer. All slices have a length stored alongside the reference.
Main types:
&[T] — immutable slice&mut [T] — mutable slice&str (essentially a byte slice, always a valid UTF-8)Slice safety is ensured at the compiler and runtime level: any attempt to access an element out of slice bounds will cause a panic at runtime, and no undefined behavior like in C/C++ will occur.
Example:
let v = vec![1, 2, 3, 4, 5]; let s: &[i32] = &v[1..4]; // slice, references elements 2, 3, 4 println!("{:?}", s); // [2, 3, 4] // s[3]; // panic! (out of bounds)
Can slices be empty? What is the difference between an empty slice and None?
Answer: Yes, slices can be empty (&[]), which means a reference to a data portion with zero length, but it is not equivalent to None. An empty slice is safe to use, while Option<&[T]> is used to distinguish whether "there is a slice at all".
Example:
let s: &[i32] = &[]; assert!(s.is_empty()); // Option<&[i32]> is used when the slice may not exist at all.
Story
In a large logging service, a programmer took a slice by a range calculated dynamically from user data. With incorrect slice calculations (for example, when start > end or if end > len), the code worked in tests but caused a panic in production, crashing the process during peak loads.
Story
In an internal library of concurrent hashing, they used &mut [T] and multiple threads concurrently took different slices of the same array. One thread modified the slice, while another took a different slice from the same memory. The program compiled, but due to incorrect division, undefined behavior could arise through unsafe code (using unsafe) if slices overlapped.
Story
In a system parser for network packets, a slice was created unsafely (raw pointer and from_raw_parts). The developer forgot to check the validity of the input packet length. As a result, an attempt to read out of bounds led to application crashes and a vulnerability (potential OOB access), which could have been avoided by proper use of safe slices.