10

I have this array

let buffer: &[u8] = &[0; 40000];

But when I want to map it like this:

*buffer.map( |x| 0xff);

I have the following error:

error[E0599]: no method named `map` found for type `&[u8]` in the current scope   
     --> src/bin/save_png.rs:12:13
    | 
 12 |     *buffer.map( |x| 0xff); //.map(|x| 0xff);
    |             ^^^
    |
    = note: the method `map` exists but the following trait bounds were not satisfied:
            `&mut &[u8] : std::iter::Iterator`
            `&mut [u8] : std::iter::Iterator`

I tried several ways to do the elements mutable but I can't get the right syntax. Anyone have experience? I'm trying to work with a png image buffer.

1 Answer 1

14

The type &[T] doesn't have a map method. If you look at the error message, it is telling you that a method called map exists but it won't work for &mut &[u8] or &mut [u8] because those types do not implement Iterator. Arrays and other collections usually have a method, or set of methods, for creating an iterator. For a slice or an array, you have the choice of either iter() (iterating over references) or into_iter() (iterating over moved values and consuming the source collection).

Usually, you'll also want to collect the values into some other collection:

let res: Vec<u8> = buffer
    .iter()
    .map(|x| 0xff)
    .collect();
Sign up to request clarification or add additional context in comments.

6 Comments

Can you get an array back, instead of converting to Vec?
@Ixx you can't get an array back because .collect() doesn't know how long the input is, and arrays are of fixed length in rust. You can see all the things you can collect into by seeing what implements FromIterator: doc.rust-lang.org/std/iter/trait.FromIterator.html#implementors
It would be nice to implement map directly on array that can return the same type.
@TimMB That is how it is done in languages like Javascript because these languages aim to prioritise simplicity over performance. If map was a method of slice or Vec then it would need to allocate a new Vec each time it is called. The API design in Rust means that you only allocate when you specifically choose to do so (typically by collecting), and you can build complex iterator chains that do no new allocating at all.
And FWIW, if you really want that kind of API, you can create it yourself with an extension trait which you can implement for [T].
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.