4

I have a mutable slice, and I want to replace its prefix if it equals a certain slice.

I tried this:

let len = prefix.len();

if slice.starts_with(prefix) {
    slice[.. len - 1] = subst;
}

Playground

However,

error[E0277]: the size for values of type `[{integer}]` cannot be known at compilation time
  --> src/main.rs:13:9
   |
13 |         slice[.. len - 1] = *subst;
   |         ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time

(Let's forget about the other type error in the playground; in my code, I have proper slices instead of arrays.)

I understand this as saying "The slices might have different length, so you cannot do this".

However, how can I do this when I explicitly checked that the lengths are the same?

DrunkCoder
  • 379
  • 2
  • 9

1 Answers1

4

You should try split_at_mut(), something like this:

let len = prefix.len();
if slice.starts_with(prefix) {
    let (left, _right) = slice.split_at_mut(len);
    left.copy_from_slice(subst);
}

There is also explanation about this specific problem here: copy_from_slice()


Edit: As Jmb stated in a comment, split_at_mut() is not needed:

let len = prefix.len();
if slice.starts_with(prefix) {
    slice[..len].copy_from_slice(subst);
}
vallentin
  • 23,478
  • 6
  • 59
  • 81
yolenoyer
  • 8,797
  • 2
  • 27
  • 61
  • 1
    No need for `split_at_mut`, [`copy_from_slice` can be used directly: `slice[.. len - 1].copy_from_slice (subst)`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7fb92daeb8dd49ae0fd5f61fd13acec4) – Jmb Mar 01 '21 at 07:37
  • @Jmb: indeed it's not needed; edited my answer – yolenoyer Mar 01 '21 at 08:24