Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does slicing a string copy the underlying data?

In Rust, if I wanted read-only access to one &str across multiple contexts without copying the actual underlying data, am I correct in thinking that I just use a slice?

Example

let original_string = "here's a string";

let slice = &original_string[0..3];

Or would something like Rc<str> be needed?

like image 213
Holden Perkins Avatar asked May 11 '26 12:05

Holden Perkins


2 Answers

Any reference type &T or &mut T (including slice types like &str or &[T]) will only borrow data, and will not implicitly copy or move data when used.

You can explicitly copy from a reference to a type implementing Copy by dereferencing it with *, or from a reference to a type implementing Clone by calling the clone method. You can also explicitly move out of a mutable reference by replacing it with a different value, for example with std::mem::take or std::mem::replace.

Any data that's borrowed by at least one shared reference &T must be read only for the lifetime of that reference, except for data inside a container with interior mutability, such as Cell<T>, RefCell<T>, Mutex<T> and AtomicU32.

Typically, the biggest limitation of using references is that their lifetime must be shorter than the lifetime of the owner of the data. In some cases, this may make code hard or impossible to express purely with references and lifetimes. Reference-counting pointers like Rc<T> and Arc<T> can help, as they generally act similar to shared references &T, except that instead of borrowing data from some other location, the data is moved into the Rc/Arc and then the data ownership is shared between all clones of that Rc/Arc, elimitating the need for reference lifetimes, but at a small runtime cost.

like image 83
Frxstrem Avatar answered May 14 '26 11:05

Frxstrem


read-only access to one &str

you are right, the codes did not copy the string, &str basically includes 2 parts, a pointer and a len, thus

    let original_string = "here's a string";
    let slice = &original_string[0..3];

    println!("{:?}", original_string.as_ptr());
    println!("{:?}", original_string.len());
    println!("{:?}", slice.as_ptr());
    println!("{:?}", slice.len());

The output would look like

0x1074d4ee3
15
0x1074d4ee3
3
like image 45
ggaowp Avatar answered May 14 '26 11:05

ggaowp



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!