Originally published on php2rust.dev — part of the PHP to Rust course. View this lesson on the original site.
In PHP, array_slice() gives you a new array with part of the data. In Rust, a slice is simpler: it points at part of an existing array or Vec (type &[T]). It does not copy the whole list into something new. For text, &str is the same idea: a view into part of a string.
You pick the range each time (e.g. &arr[1..4]). A different range → you “see” a different number of elements; the original array/Vec is unchanged. To grow a list you use Vec and push, not a slice.
PHP has nothing quite like “just a view into the same memory”; array_slice copies. Rust’s slice borrows instead.
What “borrows” means here
Borrow is Rust’s word for: “I’m allowed to use this data for a while, but I don’t own it.” The owner is still the array, Vec, or String that actually holds the values. The slice is only a temporary view tied to that owner.
So “borrow instead of copy” means: the elements stay where they are; your slice just says “those ones, right there.” You’re not given a separate heap allocation that duplicates the list (unlike a fresh PHP array from array_slice).
Rust then tracks that relationship: while a slice is in use, the compiler won’t let the owner disappear or be changed in a way that would leave the slice pointing at freed or invalid memory. (PHP doesn’t check that for you at compile time.) A &[T] slice is an immutable borrow, read-only unless you use &mut [T], which is a mutable borrow with stricter rules (only one at a time).
If I change the slice, does the original array change?
- With
&[T]you cannot change elements, the compiler treats the slice as read-only. - With
&mut [T]you can change elements (e.g.slice[0] = 99), and you are changing the same memory as the underlying array orVec. There is still only one buffer; the slice is just another way to access part of it. (You need the owner to bemutas well, e.g.let mut arr = …; let s = &mut arr[1..3];.)
So: not a copy of the data, immutable slice = look but don’t touch; mutable slice = touch, and the owner sees the update.
Is this mostly about performance?
Partly. Slices often avoid copies and extra allocations, which can make programs faster and use less memory, especially with large lists.
But Rust’s main goal with borrows is safety: the compiler proves you’re not reading freed memory or breaking rules with simultaneous mutation. Performance is a welcome side effect of not copying everything by default, not the only story.
Why you’d use a slice (use cases)
- One function for “some items”, You write
fn total(nums: &[i32]) -> i32once. Callers can pass a whole array, a wholeVec, or only a range (&arr[1..4]) without copying the data. In PHP you’d pass an array and hope the shape matches; in Rust the type says “I only need to read this contiguous chunk.” - Less copying, If the list is large, taking
&[T]avoids building a new buffer (unlikearray_slicewhen you only need to inspect or sum values). - Strings, Lots of Rust APIs take
&str, so one helper can work on a literal, aString, or a substring (&s[0..3]) without allocating a new owned string each time.
fn total(nums: &[i32]) -> i32 {
nums.iter().sum()
}
fn main() {
let arr = [1, 2, 3, 4, 5];
let v = vec![10, 20];
println!("{}", total(&arr)); // all five
println!("{}", total(&v)); // whole vec
println!("{}", total(&arr[1..4])); // middle bit only: 2+3+4
}
Rust
fn main() {
let arr = [10, 20, 30, 40, 50];
let slice: &[i32] = &arr[1..4]; // [20, 30, 40]
println!("Slice: {:?}", slice);
println!("Length: {}", slice.len());
// Slice of a String
let s = String::from("hello");
let hello: &str = &s[0..5]; // string slice
println!("hello: {}", hello);
}
&[T]is a slice type.- Range
1..4= indices 1, 2, 3 (4 excluded). - Slices are references; no copy of data.
PHP
<?php
$arr = [10, 20, 30, 40, 50];
$slice = array_slice($arr, 1, 3); // [20, 30, 40], new array
echo "Slice: " . json_encode($slice) . "\n";
echo "Length: " . count($slice) . "\n";
array_slice() returns a new array (a copy). PHP has no native non-owning slice type.
Comparison
- Rust:
&[T], borrow part of an array/Vec; range picks how many elements you see.&str, borrow part of a string’s text. - PHP:
array_slice(), new array with a copy of that region.
References
What's next
Next: Strings.
From PHP to Rust — Rust Syntax and Functions